Files
QualcommWireless/docs/NATIVE_WIFI.md
T
Erwan cc3fff7dc7 docs(wifi): documenter le postmortem 16, la persistance NVRAM et les 7 paliers d'amorçage
- Breakthroughs & Rétro-ingénierie :
  * Rédaction détaillée du Postmortem 16 (analyse du panic lié à l'incompatibilité vtable IO80211WorkQueue / IOWorkLoop dans super::start()).
  * Documentation du mécanisme de non-volatilité de la NVRAM SPI Flash UEFI et explication de l'impossibilité d'écriture sur fichier APFS en early-boot.
  * Cartographie complète des appels internes de IO80211SkywalkInterface::start() vers CCPipe, CCStream, IO80211PeerManager et allocIO80211RecursiveLock().

- Modifications apportées :
  * docs/ISSUES_AND_POSTMORTEMS.md : ajout de la section Postmortem 16.
  * docs/NATIVE_WIFI.md : ajout de la section 6 décrivant les 7 paliers Skywalk (qcom_step) et la télémétrie NVRAM (qcom_stage).

- Déploiement :
  * QualcommWifi.kext déployé dans /Volumes/EFI/EFI/OC/Kexts/.
  * config.plist configuré avec QualcommWifi.kext Enabled=True et qcom_step=5.
2026-10-19 00:01:31 +02:00

9.6 KiB

Pile Wi-Fi Native macOS pour Qualcomm WCN7850

Ce document détaille l'implémentation de la pile Wi-Fi native (IO80211Controller) pour le chipset Qualcomm FastConnect 7800 (WCN7850) sous macOS Tahoe (26.x / Darwin 25) et macOS Sequoia (15.x / Darwin 24).


1. Pourquoi le Wi-Fi Natif et non l'Émulation Ethernet ?

Dans les premières ébauches de pilotes non officiels pour macOS, certains projets choisissaient d'émuler une interface réseau filaire standard (IOEthernetController), en masquant les détails Wi-Fi dans un daemon externe (comme HeliPort).

Cependant, cette approche présente des limitations rédhibitoires :

  • ❌ Pas d'intégration dans le menu Wi-Fi natif du Centre de Contrôle macOS.
  • ❌ Absence de géolocalisation par points d'accès Wi-Fi (CoreLocation).
  • ❌ Incompatibilité totale avec les services Apple (AirDrop, AirPlay, Continuité, Universal Control).
  • ❌ Impossibilité pour les applications utilisant CoreWLAN.framework de découvrir les réseaux, obtenir le RSSI, ou basculer de canal.

QualcommWireless fait le choix d'une intégration 100% native en dérivant directement de IO80211Controller (de com.apple.iokit.IO80211Family).


2. Architecture de QualcommWifi (IO80211Controller)

graph TD
    subgraph AppleStack["Sous-Système Sans Fil Apple"]
        CC["Centre de Contrôle macOS"]
        CoreWLAN["CoreWLAN.framework"]
        AirportD["airportd (Daemon Système)"]
        Skywalk["Skywalk Family (Packet Pipeline)"]
        IO80211["IO80211Family (IO80211Controller / IO80211SkywalkInterface)"]
    end

    subgraph Driver["QualcommWifi (Driver Kernel)"]
        IoctlHandler["Gestionnaire IOCTL Apple80211 (handleCardSpecific / apple80211Request)"]
        ScanEngine["Moteur de Scan (Passif / Actif / Multicanal)"]
        RingDMA["Gestionnaire DMA & Anneaux MHI (CR / ER / TR)"]
        FirmwarePipeline["Pipeline de Démarrage BHI / AMSS"]
        Windowing["Module Fenêtrage PCIe BAR0 (0x310c)"]
    end

    subgraph Hardware["Qualcomm WCN7850 (PCIe 0x17cb:0x1107)"]
        PBL["Primary Boot Loader (PBL)"]
        MHIHardware["MHI Engine (Modem Host Interface)"]
        WlanFirmware["Firmware AMSS Wi-Fi 7 (ath12k/WCN7850)"]
        MacPhy["MAC / Baseband PHY (802.11a/b/g/n/ac/ax/be)"]
    end

    CC --> AirportD
    CoreWLAN --> AirportD
    AirportD -->|Skywalk / IO80211| IO80211
    Skywalk --> IO80211
    IO80211 --> IoctlHandler
    IoctlHandler --> ScanEngine
    ScanEngine --> RingDMA
    RingDMA --> Windowing
    FirmwarePipeline --> Windowing
    Windowing --> PBL
    PBL --> MHIHardware
    MHIHardware --> WlanFirmware
    WlanFirmware --> MacPhy

3. Communication Matérielle : MHI & Fenêtrage PCIe

3.1. Gestion du Fenêtrage PCIe BAR0

Le bus PCIe expose un espace MMIO BAR0 de 512 Ko. Or, les composants internes du WCN7850 (SoC, registres MHI, BHI, mémoires partagées) s'étendent sur plusieurs mégaoctets :

  • Registre de sélection de fenêtre : 0x310c (ATH12K_PCI_WINDOW_REG_ADDRESS).
  • Calcul de la fenêtre : Pour une adresse matérielle A \ge 512\text{ Ko}, le numéro de fenêtre est calculé par : \text{window} = (A \gg 19) \ \& \ 0x3F \text{offset} = 0x80000 \ | \ (A \ \& \ 0x7FFFF)
  • Le pilote met à jour dynamiquement fCurrWindow avant d'effectuer les écritures/lectures MMIO nécessaires.

3.2. Séquence de Boot MHI (Modem Host Interface)

  1. Reset initial via ATH12K_PCI_SOC_GLOBAL_RESET (0x3008).
  2. Boot Host Interface (BHI/BHIe) :
    • Initialisation des vecteurs de transmission (ATH12K_BHIE_TXVECADDR_LOW / _HIGH).
    • Transfert de l'image de firmware principale (amss.bin, taille ~6 Mo) et du fichier de calibration carte (board-2.bin, ~2.4 Mo).
    • Validation de la signature et exécution dans le SoC WCN7850.
  3. Transition d'environnement MHI :
    • Transition de l'état PBL (Primary Boot Loader) vers AMSS (Advanced Mobile Subscriber Software).
    • Configuration des anneaux MHI :
      • Command Ring (CR) : Envoi des requêtes d'initialisation WMI.
      • Event Ring (ER) : Réception asynchrone des événements et interruptions MSI-X.
      • Transfer Rings (TR) : Transmission et réception des paquets réseau 802.11.

4. ABI IO80211Controller sous macOS Tahoe (Darwin 25) et IOCTLs Apple80211

4.1. VTable Skywalk unifiée de IO80211Controller sous macOS Tahoe (__IO80211_TARGET=260000)

Sous macOS Tahoe (IO80211Family v1200.13.1, source 1566.5), IO80211Controller (taille d'instance 0x128 = 296 octets) a achevé sa transition vers IO80211SkywalkInterface avec une vtable de 463 entrées (slots 394 à 462 après IOEthernetController) :

  • slot 394 (0xc50) : isCommandProhibited(int)
  • slot 403 (0xc98) : handleCardSpecific(IO80211SkywalkInterface*, unsigned long, void*, bool) (remplace apple80211Request / apple80211SkywalkRequest)
  • slots 404..406 (0xca0..0xcb0) : hardwareOutputQueueDepth(void), performCountryCodeOperation(IO80211CountryCodeOp), dataLinkLayerAttachComplete(void) (sans paramètre IO80211Interface*)
  • slots 408..415 (0xcc0..0xcf8) : accesseurs typés purs virtuels (getDRIVER_VERSION, getHARDWARE_VERSION, getCARD_CAPABILITIES, getPOWER, setPOWER, getCOUNTRY_CODE, setCOUNTRY_CODE, setGET_DEBUG_INFO)
  • slots 424 & 432 : getLogger(void) const et getFaultReporterFromDriver(void)

4.2. Table des requêtes Apple80211 prises en charge

Pour qu'un pilote soit reconnu par le sous-système Wi-Fi de macOS, il répond aux requêtes APPLE80211_IOC_* :

Opération IOCTL Rôle dans le système macOS
APPLE80211_IOC_SSID (GET / SET) Lecture et définition du réseau Wi-Fi cible.
APPLE80211_IOC_SCAN_REQ_MULTIPLE Déclenchement d'un scan Wi-Fi (recherche des réseaux environnants pour l'interface graphique).
APPLE80211_IOC_SCAN_RESULT Remontée unitaire ou groupée des points d'accès découverts (SSID, BSSID, RSSI, Beacon, Type de sécurité WPA2/WPA3).
APPLE80211_IOC_BSSID_LIST Fourniture de la liste des BSSIDs disponibles dans le cache.
APPLE80211_IOC_CHANNEL (GET / SET) Lecture et bascule de canal (2.4 GHz, 5 GHz, 6 GHz).
APPLE80211_IOC_CHANNEL_INFO Enumération des canaux supportés (canaux 1 à 14, bandes 5 GHz UNII-1 à UNII-4, et canaux 6 GHz UNII-5 à UNII-8 pour le Wi-Fi 6E/7).
APPLE80211_IOC_PHY_MODE Déclaration des modes PHY supportés (APPLE80211_MODE_11BE, 11AX, 11AC, 11N, 11G, 11A, 11B).
APPLE80211_IOC_STATE État de la machine à états de l'interface (RUN, INIT, SCAN, AUTH, ASSOC).
APPLE80211_IOC_RSSI Niveau de signal courant (en dBm, typiquement entre -30 dBm et -95 dBm).
APPLE80211_IOC_RATE Débit négocié courant (jusqu'aux débits Wi-Fi 7 EHT MCS 0-13).
APPLE80211_IOC_TXPOWER Puissance d'émission radio déclarée.

5. Prise en Charge du Wi-Fi 7 (802.11be)

La puce WCN7850 introduit les caractéristiques Wi-Fi 7 suivantes, intégrées dans la table des capacités du pilote :

  • Canaux 320 MHz ultra-larges en bande 6 GHz.
  • Modulation 4096-QAM (4K-QAM) augmentant la densité de données de 20% par rapport au 1024-QAM du Wi-Fi 6.
  • Multi-Link Operation (MLO) : Capacité matérielle d'agréger ou de basculer dynamiquement entre plusieurs bandes (ex. 5 GHz + 6 GHz) pour une latence ultra-faible.
  • Preamble Puncturing : Évitement automatique des sous-canaux brouillés pour maximiser la bande passante utilisable.

6. Séquence d'Amorçage par Paliers Skywalk et Télémétrie NVRAM

Pour isoler précisément chaque point de blocage sous macOS Tahoe sans risquer de Kernel Panic aveugle, l'initialisation de l'interface Skywalk est segmentée en 7 stades distincts, contrôlés dynamiquement par les boot-args OpenCore :

Stade (qcom_step) Opération Exécutée Rôle & Mécanisme Bas-Niveau Statut Actuel
Stade 1 createSkywalkInterface() Allocation mémoire 0x128 (nwEm) + constructeur MetaClass + initIvars() VALIDÉ
Stade 2 fSkywalkInterface->init(this, &mac) Initialisation de l'interface réseau Ethernet Skywalk avec l'adresse MAC VALIDÉ
Stade 3 fSkywalkInterface->setInterfaceRole(1) Configuration du rôle en mode Infrastructure (1) VALIDÉ
Stade 4 attachInterface(fSkywalkInterface, this) Liaison de l'interface Skywalk au contrôleur IO80211Controller (slot 441) VALIDÉ
Stade 5 fSkywalkInterface->attach(this) Enregistrement de l'interface dans l'IORegistry (gIOServicePlane) VALIDÉ (Visibilité confirmée dans IORegistry)
Stade 6 fSkywalkInterface->start(this) Démarrage complet du moteur Skywalk : rattachement PMtree, création des flux CoreCapture CCPipe, allocation du IO80211PeerManager et des verrous récursifs EN COURS (Traçage fin via cb_getWorkQueue_1/2 et cb_allocLock)
Stade 7 fSkywalkInterface->registerService() Publication globale du service réseau pour airportd et l'interface utilisateur macOS En attente de validation du Stade 6

6.1. Télémétrie et Persistance NVRAM (qcom_stage)

En phase précoce d'amorçage (early boot), le snapshot racine APFS est scellé cryptographiquement et monté en lecture seule stricte, rendant toute écriture sur fichier disque impossible. Le pilote exploite donc l'API PEWriteNVRAMProperty pour inscrire chaque jalon de progression directement dans la puce SPI Flash UEFI de la carte mère sous la variable qcom_stage. Cette variable survit aux plantages matériels, aux redémarrages forcés ainsi qu'aux sessions Linux.