diff --git a/repos/dde_linux/patches/i915_irq.patch b/repos/dde_linux/patches/i915_irq.patch new file mode 100644 index 0000000000..3430832c11 --- /dev/null +++ b/repos/dde_linux/patches/i915_irq.patch @@ -0,0 +1,14 @@ +intel_fb: avoid pagefault in fliphandler + +--- src/linux/drivers/gpu/drm/i915/display/intel_display_irq.c ++++ src/linux/drivers/gpu/drm/i915/display/intel_display_irq.c +@@ -349,7 +349,8 @@ static void flip_done_handler(struct drm_i915_private *i915, + + crtc_state->event = NULL; + +- drm_crtc_send_vblank_event(&crtc->base, e); ++ if (e) ++ drm_crtc_send_vblank_event(&crtc->base, e); + + spin_unlock_irqrestore(&dev->event_lock, irqflags); + } diff --git a/repos/dde_linux/patches/iwlwifi_break_busy_loop.patch b/repos/dde_linux/patches/iwlwifi_break_busy_loop.patch new file mode 100644 index 0000000000..7f1960991a --- /dev/null +++ b/repos/dde_linux/patches/iwlwifi_break_busy_loop.patch @@ -0,0 +1,17 @@ +The 'iwl_pcie_spin_for_iml()' implementation contains a loop that +relies on jiffies being constantly incremented due to its use of +'time_before()'. As this is also a macro, rather than playing CPP +shenanigens we fallback to altering the code. + +--- src/linux/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c ++++ src/linux/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +@@ -431,6 +431,9 @@ + /* Keep the CPU and device busy. */ + value = iwl_read32(trans, CSR_LTR_LAST_MSG); + loops++; ++ ++ /* force scheduling to increase jiffies */ ++ cpu_relax(); + } + + IWL_DEBUG_INFO(trans, diff --git a/repos/dde_linux/patches/iwlwifi_enable_irq_before_pnvm.patch b/repos/dde_linux/patches/iwlwifi_enable_irq_before_pnvm.patch new file mode 100644 index 0000000000..a3dc5ef469 --- /dev/null +++ b/repos/dde_linux/patches/iwlwifi_enable_irq_before_pnvm.patch @@ -0,0 +1,43 @@ +From b4024bb479b2ee9b34125b65472a0537043c8dc4 Mon Sep 17 00:00:00 2001 +From: Chris Rogers +Date: Thu, 1 Sep 2022 15:56:14 +0200 +Subject: [PATCH] Re-enable interrupts before loading PNVM. + +For cards in the AX210+ family that advertise a SKU and try to load a PNVM, +in the non-MSIX (MSI) case the normal firmware load flow disables all interrupts +from the card except ALIVE and RX. This is primarily to enforce the driver's +assumption that we will not receive RF_KILL before the firmware has finished +loading, or else an unintelligible error is dumped. + +This unfortunately also prevents us from responding to an interrupt from the +card after 'kicking the doorbell' (UREG_DOORBELL_TO_ISR6_PNVM). We therefore +wait until the specified timeout and report "Timeout waiting for PNVM load!" +and fail out of driver initialization. + +This patch re-enables interrupts prior to loading the PNVM so we can respond +properly when the card notifies us of a successful PNVM load. Since the FW is +technically 'ALIVE' at this point, it should be ok to also re-enable RF_KILL. +--- + drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +index f041e77af059..ec982ddce196 100644 +--- src/linux/drivers/net/wireless/intel/iwlwifi/mvm/fw.c ++++ src/linux/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +@@ -423,6 +423,15 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, + /* if reached this point, Alive notification was received */ + iwl_mei_alive_notif(true); + ++ /* ++ * re-enable interrupts so we can get a response from ++ * the card when kicking the doorbell during pnvm load. ++ * This is only needed in the non-msix case. FW is ++ * technically alive at this point so re-enabling rf-kill ++ * interrupt is probably ok. ++ */ ++ iwl_trans_interrupts(mvm->trans, true); ++ + ret = iwl_pnvm_load(mvm->trans, &mvm->notif_wait, + &mvm->fw->ucode_capa); + if (ret) { diff --git a/repos/dde_linux/patches/iwlwifi_limit_rx_bufs.patch b/repos/dde_linux/patches/iwlwifi_limit_rx_bufs.patch new file mode 100644 index 0000000000..01158fde0e --- /dev/null +++ b/repos/dde_linux/patches/iwlwifi_limit_rx_bufs.patch @@ -0,0 +1,22 @@ +iwlwifi: limit rx bufs to 2048 + +Recent devices are configured with 4096 RX pages that lead to an +increased memory usage. For the moment lower the amount to 2048 +and treat in potientially lower throughput for more conservative +memory consumption. + +diff --git src/linux/drivers/net/wireless/intel/iwlwifi/pcie/drv.c src/linux/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +index dea4d6478..f063e22c1 100644 +--- src/linux/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ src/linux/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -1467,6 +1467,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + u16_get_bits(link_status, PCI_EXP_LNKSTA_CLS); + } + ++ /* limit some recent cards that use 4096 */ ++ if (trans_pcie->num_rx_bufs > 2048) ++ trans_pcie->num_rx_bufs = 2048; ++ + ret = iwl_trans_init(iwl_trans); + if (ret) + goto out_free_trans; diff --git a/repos/dde_linux/patches/lxip_checksum_32.patch b/repos/dde_linux/patches/lxip_checksum_32.patch new file mode 100644 index 0000000000..9c2b1a7396 --- /dev/null +++ b/repos/dde_linux/patches/lxip_checksum_32.patch @@ -0,0 +1,30 @@ +CONFIG_X86_USE_PPRO_CHECKSUM is a 'def_bool y' and gets re-enabled by +'make olddefconfig'. The PPRO version contains text relocations which we cannot +have in binaries (e.g., 'lea 45f(%ebx ...).'). + +diff --git src/linux/arch/x86/lib/checksum_32.S src/linux/arch/x86/lib/checksum_32.S +index 23318c338..0eba84857 100644 +--- src/linux/arch/x86/lib/checksum_32.S ++++ src/linux/arch/x86/lib/checksum_32.S +@@ -36,8 +36,9 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) + */ + + .text +- +-#ifndef CONFIG_X86_USE_PPRO_CHECKSUM ++ ++/* use version without text relocations */ ++#if 1 + + /* + * Experiments with Ethernet and SLIP connections show that buff +@@ -264,7 +265,8 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, + 9999: y; \ + _ASM_EXTABLE_TYPE(9999b, 7f, EX_TYPE_UACCESS | EX_FLAG_CLEAR_AX) + +-#ifndef CONFIG_X86_USE_PPRO_CHECKSUM ++/* use version without text relocations */ ++#if 1 + + #define ARGBASE 16 + #define FP 12 diff --git a/repos/dde_linux/patches/lxip_ip_config.patch b/repos/dde_linux/patches/lxip_ip_config.patch new file mode 100644 index 0000000000..fd7f5c51de --- /dev/null +++ b/repos/dde_linux/patches/lxip_ip_config.patch @@ -0,0 +1,73 @@ +This patch makes the boot DHCP re-connectable. + +diff --git src/linux/net/ipv4/ipconfig.c src/linux/net/ipv4/ipconfig.c +index c56b6fe6f..cdb9cd83e 100644 +--- src/linux/net/ipv4/ipconfig.c ++++ src/linux/net/ipv4/ipconfig.c +@@ -130,7 +130,7 @@ int ic_proto_enabled __initdata = 0 + static int ic_host_name_set __initdata; /* Host name set by us? */ + + __be32 ic_myaddr = NONE; /* My IP address */ +-static __be32 ic_netmask = NONE; /* Netmask for local subnet */ ++__be32 ic_netmask = NONE; /* Netmask for local subnet */ + __be32 ic_gateway = NONE; /* Gateway IP address */ + + #ifdef IPCONFIG_DYNAMIC +@@ -156,7 +156,7 @@ static int ic_proto_used; /* Protocol used, if any */ + #else + #define ic_proto_used 0 + #endif +-static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */ ++__be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */ + static __be32 ic_ntp_servers[CONF_NTP_SERVERS_MAX]; /* NTP server IP addresses */ + static u8 ic_domain[64]; /* DNS (not NIS) domain name */ + +@@ -431,6 +431,33 @@ static int __init ic_setup_routes(void) + return 0; + } + ++static int __init ic_delete_routes(void) ++{ ++ /* No need to delete device routes, only the default route... */ ++ ++ if (ic_gateway != NONE) { ++ struct rtentry rm; ++ int err; ++ ++ memset(&rm, 0, sizeof(rm)); ++ if ((ic_gateway ^ ic_myaddr) & ic_netmask) { ++ pr_err("IP-Config: Gateway not on directly connected network\n"); ++ return -1; ++ } ++ set_sockaddr((struct sockaddr_in *) &rm.rt_dst, 0, 0); ++ set_sockaddr((struct sockaddr_in *) &rm.rt_genmask, 0, 0); ++ set_sockaddr((struct sockaddr_in *) &rm.rt_gateway, ic_gateway, 0); ++ rm.rt_flags = RTF_UP | RTF_GATEWAY; ++ if ((err = ip_rt_ioctl(&init_net, SIOCDELRT, &rm)) < 0) { ++ pr_err("IP-Config: Cannot delete default route (%d)\n", ++ err); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ + /* + * Fill in default values for all missing parameters. + */ +@@ -1725,6 +1752,14 @@ static int __init ip_auto_config_setup(char *addrs) + ic_set_manually = 1; + ic_enable = 1; + ++ ic_delete_routes(); ++ ++ ic_myaddr = NONE; ++ ic_netmask = NONE; ++ ic_gateway = NONE; ++ ic_servaddr = NONE; ++ ic_got_reply = 0; ++ + /* + * If any dhcp, bootp etc options are set, leave autoconfig on + * and skip the below static IP processing. diff --git a/repos/dde_linux/patches/usb_net_cdc_ncm.patch b/repos/dde_linux/patches/usb_net_cdc_ncm.patch new file mode 100644 index 0000000000..d6499df770 --- /dev/null +++ b/repos/dde_linux/patches/usb_net_cdc_ncm.patch @@ -0,0 +1,25 @@ +NCM tries to batch TX packets using timeouts (500us) and does not send packets +before 3 packets are in the submit queue. Timeouts take milliseconds on +dde_linux which leads to delayed ACKs and poor performance for the RX case. +Therefore, we send small packets (<100 Bytes) immediately without batching (it +might be an ACK or last packet of a larger transfer). + +diff --git src/linux/drivers/net/usb/cdc_ncm.c src/linux/drivers/net/usb/cdc_ncm.c +index db05622f1..4ad2bdb17 100644 +--- src/linux/drivers/net/usb/cdc_ncm.c ++++ src/linux/drivers/net/usb/cdc_ncm.c +@@ -1356,6 +1356,14 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + } + skb_put_data(skb_out, skb->data, skb->len); + ctx->tx_curr_frame_payload += skb->len; /* count real tx payload data */ ++ ++ /* ++ * send small packets immediately (e.g., TCP ACKS), just batch with large ++ * payloads ++ */ ++ if (skb->len < 100) ++ ready2send = 1; ++ + dev_kfree_skb_any(skb); + skb = NULL; + diff --git a/repos/dde_linux/patches/usb_net_pinephone.patch b/repos/dde_linux/patches/usb_net_pinephone.patch new file mode 100644 index 0000000000..82f8632490 --- /dev/null +++ b/repos/dde_linux/patches/usb_net_pinephone.patch @@ -0,0 +1,23 @@ +The PinePhone Modems' CDC Ethernet Interface does not respond if RX/TX queue size +is greater 12 (experimentally determined), the default would be 60, meaning 60 +RX Bulk URBs are sent at once to the device. + +diff --git src/linux/drivers/net/usb/usbnet.c src/linux/drivers/net/usb/usbnet.c +index 2d14b0d78..d8c566b8c 100644 +--- src/linux/drivers/net/usb/usbnet.c ++++ src/linux/drivers/net/usb/usbnet.c +@@ -356,6 +356,14 @@ EXPORT_SYMBOL_GPL(usbnet_skb_return); + void usbnet_update_max_qlen(struct usbnet *dev) + { + enum usb_device_speed speed = dev->udev->speed; ++ struct usb_device_descriptor *descr = &dev->udev->descriptor; ++ ++ /* Quectel EG25-G does not respond on queue size > 12 */ ++ if (descr->idVendor == 0x2c7c && descr->idProduct == 0x0125) { ++ printk("Quectel EG25-G detected limiting TX/RX queue size to 12 (from 60)\n"); ++ dev->rx_qlen = dev->tx_qlen = 12; ++ return; ++ } + + if (!dev->rx_urb_size || !dev->hard_mtu) + goto insanity; diff --git a/repos/dde_linux/patches/usb_net_smsc95xx.patch b/repos/dde_linux/patches/usb_net_smsc95xx.patch new file mode 100644 index 0000000000..b143d75158 --- /dev/null +++ b/repos/dde_linux/patches/usb_net_smsc95xx.patch @@ -0,0 +1,19 @@ +Remove FLAG_LINK_INTR because otherwiese usbnet.c will set the curruent link +state to down during initialization. Currently we do not support link-state +changes for SMSC95XX because the driver uses mdio/phy/irqchip infrastructure +that is hard to enable. Therefore, the driver must be started with NIC whose +link is up. + +diff --git src/linux/drivers/net/usb/smsc95xx.c src/linux/drivers/net/usb/smsc95xx.c +index 8e82184be..996b0011c 100644 +--- src/linux/drivers/net/usb/smsc95xx.c ++++ src/linux/drivers/net/usb/smsc95xx.c +@@ -2012,7 +2012,7 @@ static const struct driver_info smsc95xx_info = { + .tx_fixup = smsc95xx_tx_fixup, + .status = smsc95xx_status, + .manage_power = smsc95xx_manage_power, +- .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR, ++ .flags = FLAG_ETHER | FLAG_SEND_ZLP, + }; + + static const struct usb_device_id products[] = { diff --git a/repos/dde_linux/patches/workqueue_deadlock.patch b/repos/dde_linux/patches/workqueue_deadlock.patch new file mode 100644 index 0000000000..ca6786a9ea --- /dev/null +++ b/repos/dde_linux/patches/workqueue_deadlock.patch @@ -0,0 +1,20 @@ +This patch increases the amount of worker that will be spawned upon a work queue +when a work is submitted. The patch implies that three workers will be used for +three works (before it was one). The fourth work will be queued. + +diff --git src/linux/kernel/workqueue.c src/linux/kernel/workqueue.c +index 8c7bafbee..053eed60c 100644 +--- src/linux/kernel/workqueue.c ++++ src/linux/kernel/workqueue.c +@@ -826,7 +826,10 @@ static bool work_is_canceling(struct work_struct *work) + */ + static bool need_more_worker(struct worker_pool *pool) + { +- return !list_empty(&pool->worklist) && !pool->nr_running; ++ /* ++ * Assume two works can deadlock and make a third available ++ */ ++ return !list_empty(&pool->worklist) && pool->nr_running < 3; + } + + /* Can I start working? Called from busy but !running workers. */ diff --git a/repos/dde_linux/ports/linux.hash b/repos/dde_linux/ports/linux.hash new file mode 100644 index 0000000000..63ad33ef51 --- /dev/null +++ b/repos/dde_linux/ports/linux.hash @@ -0,0 +1 @@ +403e8fecb5e0303605e2c7b913089710e66ad3d6 diff --git a/repos/dde_linux/ports/linux.port b/repos/dde_linux/ports/linux.port new file mode 100644 index 0000000000..1f645de54b --- /dev/null +++ b/repos/dde_linux/ports/linux.port @@ -0,0 +1,23 @@ +LICENSE := GPLv2 +VERSION := 6.6.47 +DOWNLOADS := linux.archive + +URL(linux) := https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-$(VERSION).tar.xz +SHA(linux) := d43376c9e9eaa92bb1b926054bd160d329c58a62d64bd65fe1222c11c6564f50 +DIR(linux) := src/linux + +# +# Patches +# +PATCH_FILES := i915_irq.patch \ + iwlwifi_break_busy_loop.patch \ + iwlwifi_enable_irq_before_pnvm.patch \ + iwlwifi_limit_rx_bufs.patch \ + lxip_checksum_32.patch \ + lxip_ip_config.patch \ + usb_net_cdc_ncm.patch \ + usb_net_pinephone.patch \ + usb_net_smsc95xx.patch \ + workqueue_deadlock.patch + +PATCHES += $(addprefix patches/,$(PATCH_FILES))