Files
xyou efa626ed17 feat: Phase 1 网络端到端打通 + FirstInit/Login/DevMode 完善
- 用户态共享网络协议栈 CODE/tools/net_stack.h(eth/ARP/IPv4/ICMP/UDP-DNS/TCP static inline,轮询模型)
- shell 内建 ping/curl/run 命令;ping.elf/curl.elf 对齐 net_stack.h 真实协议栈
- shell dev_mode 串口镜像(g_serial_mirror)便于自动化验证
- DSK 启动流程:firstInit.txt 双行格式(firstInit + dev_mode),dev_mode=1 触发 shell 自动回归测试
- FirstInit 完成→持久化 USER.CONF + 翻转 firstInit 0->1(保留 dev_mode)
- firstInit=1 时 DSK 加载 login.elf 进行用户选择 + 密码校验后再进 desktop
- 新增 CODE/login/ 登录应用、CODE/DKM/dkm_shared.h、Logo.png
- ahci/e1000/virtio_net/fat32/console_fb 驱动更新;utsm serial/block/dsk_loader 调整
- build.ps1 打包 ping.elf/curl.elf 进 SATA FAT32 根目录
- 移除 CODE/tools/bash(与 shell.elf 重复)
2026-07-26 21:07:36 +08:00

799 lines
29 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* DKM ath9k Driver — Atheros AR928x 802.11abgn WiFi
* Stage 3, optional, depends on "pci" and "irq", provides "netdev".
*
* 实现范围:
* - PCI 探测(vendor 0x168c,AR9280/9285/9287 等常见 PCIe chip)
* - BAR0 MMIO 映射(HHDM 模式,与 e1000 相同)
* - 软件复位 + RTC 唤醒序列
* - EEPROM 读取(4KB ATF EEPROM,读 MAC 地址 + 校准数据基址)
* - 简化硬件初始化(ath9k_hw_init 关键寄存器序列)
* - RX 描述符环 + beacon 接收
* - 信道切换 + 被动扫描状态机
* - 802.11 beacon IE 解析(SSID/RSSI/DS channel/RSN/RSN capabilities)
* - netdev 注册 + 扫描结果查询回调(通过 kernel_api.net.scan_*)
*
* 注意:QEMU 不支持 WiFi 网卡模拟,本驱动只能在真实硬件测试。
* 完整 ath9k HAL 寄存器初始化序列非常庞大,本驱动保留核心扫描路径,
* 部分高级特性(ANI/MRR/AGC 调优)留待硬件验证后增量完善。
*/
#include "../dkm_shared.h"
static const char *const g_depends[] = {"pci","irq"};
static const char *const g_provides[] = {"netdev"};
__attribute__((visibility("default"), used))
const struct dkm_driver_desc driver_desc = {
.magic=DKM_DRIVER_MAGIC,.abi_version=DKM_ABI_VERSION,
.desc_size=sizeof(struct dkm_driver_desc),
.name="ath9k",.version="0.1.0",.vendor="Deshab",
.driver_class=9,.stage=3,.flags=0,.priority=0,
.depends=g_depends,.depends_count=2,
.provides=g_provides,.provides_count=1,.min_kernel_abi=1,
};
/* ---- ath9k 寄存器(AR9280/9285/9287 PCIe MAC,Linux ath9k reg.h 关键子集) ---- */
#define AR_RC 0x4000u
#define AR_RC_MAC 0x00000001u
#define AR_RC_BB 0x00000002u
#define AR_RC_RPCU 0x00000004u
#define AR_RC_RDMA 0x00000008u
#define AR_RTC_RESET 0x0040u
#define AR_RTC_FORCE_WAKE 0x0044u
#define AR_RTC_FORCE_WAKE_ON 0x00000001u
#define AR_RTC_FORCE_WAKE_INT 0x00000002u
#define AR_RTC_STATUS 0x0048u
#define AR_RTC_STATUS_SHUTDOWN 0x00000001u
#define AR_RTC_STATUS_ON 0x00000002u
#define AR_RTC_SLEEP_CLK 0x004Cu
#define AR_EEPROM_CMD 0x4008u
#define AR_EEPROM_STS 0x400Cu
#define AR_EEPROM_DATA 0x4010u
#define AR_EEPROM_CMD_READ 0x00000001u
#define AR_EEPROM_CMD_RESET 0x00000004u
#define AR_EEPROM_STS_RDBUSY 0x00010000u
#define AR_EEPROM_STS_DATA_M 0x0000FFFFu
#define AR_EEPROM_STS_VALID 0x00000100u
/* MAC address registers */
#define AR_STA_ID0 0x0800u
#define AR_STA_ID1 0x0804u
#define AR_BSSMSKL 0x0808u
#define AR_BSSMSKH 0x080Cu
/* RX DMA */
#define AR_RXDP 0x0000u
#define AR_RXCFG 0x0004u
#define AR_RXCFG_ZLFDMA 0x08000000u
#define AR_MIBC 0x0044u
#define AR_CR 0x0008u
#define AR_CR_RXE 0x00000004u
#define AR_CR_RXD 0x00000001u
#define AR_RXNOPTR 0x0064u
/* Interrupts */
#define AR_IMR 0x0080u
#define AR_ISR 0x0084u
#define AR_ISR_RAC 0x00C0u
#define AR_ISR_RXOK 0x00000001u
#define AR_ISR_RXERR 0x00000002u
#define AR_ISR_RXORN 0x00000020u
#define AR_ISR_RXKINT 0x00000100u
#define AR_IMR_RXOK AR_ISR_RXOK
#define AR_IMR_RXERR AR_ISR_RXERR
#define AR_IMR_RXORN AR_ISR_RXORN
#define AR_IMR_RXKINT AR_ISR_RXKINT
/* Channel registers (PHY) */
#define AR_PHY_BASE 0x9800u
#define AR_PHY(_n) (AR_PHY_BASE + ((_n) << 2))
#define AR_PHY_CCK_DETECT AR_PHY(0x0A14)
#define AR_PHY_SYNTH_CONTROL AR_PHY(0x9874)
#define AR_PHY_RFBUS_REQ AR_PHY(0x987C)
#define AR_PHY_RFBUS_GRANT AR_PHY(0x987C)
#define AR_PHY_PLL 0x9914u
#define AR_PHY_PLL_CONTROL AR_PHY(0x9914)
/*---- RX 描述符 (ath9k RX status descriptor, 8 words = 32 bytes) ---- */
struct ath9k_rx_desc {
u32 ds_link; /* next descriptor phys (32-bit) */
u32 ds_data; /* data buffer phys (32-bit) */
u32 ds_ctl0; /* buffer len + control */
u32 ds_ctl1; /* frame type */
u32 ds_status0; /* RX status 0 */
u32 ds_status1; /* RX status 1 */
u32 ds_status2; /* RX status 2 (RSSI) */
u32 ds_status3; /* RX status 3 */
} __attribute__((packed));
#define ATH9K_RXCTL_BUF_LEN_S 0
#define ATH9K_RXCTL_BUF_LEN_M 0x00000FFFu
#define ATH9K_RXCTL_INTREQ 0x00020000u
#define ATH9K_RXSTATUS_DONE 0x00000001u
#define ATH9K_RXSTATUS_OK 0x00000002u
#define ATH9K_RXSTATUS_CRC 0x00000004u
#define ATH9K_RXSTATUS_DECRYPT_BUSY 0x00000008u
#define ATH9K_RXSTATUS_FRAME_LEN_S 0
#define ATH9K_RXSTATUS_FRAME_LEN_M 0x0000FFF8u
#define ATH9K_RX_BUF_SIZE 4096u
#define ATH9K_RX_DESC_COUNT 16u
/* ---- 802.11 帧解析 ---- */
/* frame_control: type=2 bits, subtype=4 bits */
#define IEEE80211_FTYPE_MGMT 0x0000u
#define IEEE80211_STYPE_BEACON 0x0008u
#define IEEE80211_STYPE_PROBE_RESP 0x0005u
/* Information Element IDs */
#define WLAN_EID_SSID 0
#define WLAN_EID_DS_PARAMS 3
#define WLAN_EID_RSN 48
#define WLAN_EID_VENDOR 221
#define ATH9K_MAX_SCAN_RESULTS 32u
#define ATH9K_SSID_MAX 32u
struct ath9k_scan_result {
char ssid[ATH9K_SSID_MAX + 1];
u8 bssid[6];
u8 channel;
i8 rssi;
u8 security;
};
/* 2.4GHz 信道表 (channel -> freq MHz) */
__attribute__((used))
static const u16 g_chan2g[] = {
2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
2452, 2457, 2462, 2467, 2472
};
#define ATH9K_CHAN_2G_COUNT (sizeof(g_chan2g) / sizeof(g_chan2g[0]))
/* ---- 全局状态 ---- */
static const struct dkm_log_api *g_log;
static volatile u8 *g_mmio;
static u64 g_bar0_phys;
static u8 g_mac[6];
static u16 g_pci_device_id;
static u8 g_pci_irq;
static struct dkm_dma_buffer g_rx_desc_dma;
static struct ath9k_rx_desc *g_rx_desc;
static struct dkm_dma_buffer g_rx_buf_dma[ATH9K_RX_DESC_COUNT];
static u8 *g_rx_buf[ATH9K_RX_DESC_COUNT];
static u32 g_rx_head;
static int g_rx_ready;
/* 扫描状态 */
static struct ath9k_scan_result g_scan_results[ATH9K_MAX_SCAN_RESULTS];
static u32 g_scan_count;
static int g_scanning;
/* ---- 串口日志(参考 e1000 raw_log) ---- */
#define COM1 0x3F8
/* 串口发送等待 thin wrapper — 调用 dkm 共享实现 */
static void serial_wait_tx(void) { dkm_serial_wait_tx(COM1); }
static void raw_log(const char *s) {
while (*s) {
char c = *s++;
if (c == '\n') {
serial_wait_tx();
dkm_outb(COM1, '\r');
}
serial_wait_tx();
dkm_outb(COM1, (u8)c);
}
}
static void raw_hex(const char *prefix, u64 v) {
static const char h[] = "0123456789abcdef";
raw_log(prefix);
raw_log("0x");
for (int i=15; i>=0; i--) {
serial_wait_tx();
dkm_outb(COM1, (u8)h[(v >> (i * 4)) & 0xf]);
}
raw_log("\n");
}
/* ---- PCI 配置空间 ---- */
static u32 pci_read(u8 bus, u8 dev, u8 func, u8 reg) {
return dkm_pci_read(bus, dev, func, reg);
}
static void pci_write(u8 bus, u8 dev, u8 func, u8 reg, u32 v) {
dkm_pci_write(bus, dev, func, reg, v);
}
/* ath9k PCI 设备 ID 表(vendor 0x168c Atheros) */
static int ath9k_find(u8 *bus, u8 *dev) {
for (u8 d=0; d<32; d++) {
u32 vd = pci_read(0,d,0,PCI_VENDOR_ID);
if ((vd&0xffff)==0xffff) continue;
if ((vd&0xffff)!=0x168c) continue;
u16 did = (u16)(vd>>16);
/* AR9280/9285/9287/9380/9580/9565 等常见 PCIe chip */
if (did==0x002A || did==0x002B || did==0x002C || did==0x002D ||
did==0x002E || did==0x0030 || did==0x0032 || did==0x0033 ||
did==0x0034 || did==0x0036 || did==0x0037 || did==0xAB34 ||
did==0x0029 || did==0x1A56 || did==0x2A37 || did==0x003C ||
did==0x003D || did==0x003E || did==0x0042 || did==0x0043 ||
did==0x0044 || did==0x0046 || did==0x0047 || did==0x0051 ||
did==0x0052 || did==0x0053 || did==0x0059 || did==0x005A ||
did==0x005B || did==0x005C || did==0x0061 || did==0x0063 ||
did==0x0065 || did==0x0066 || did==0x0067 || did==0x0068 ||
did==0x0069 || did==0x006A || did==0x006B || did==0x006C ||
did==0x006E || did==0x006F || did==0x0070 || did==0x0071 ||
did==0x0072 || did==0x0073 || did==0x0074 || did==0x0075 ||
did==0x0076 || did==0x0077 || did==0x0078 || did==0x0079 ||
did==0x007A || did==0x0080 || did==0x0081 || did==0x0082 ||
did==0x0083 || did==0x0085 || did==0x0086 || did==0x0087 ||
did==0x0088 || did==0x0089 || did==0x008A || did==0x008B ||
did==0x008C || did==0x008D || did==0x008E || did==0x008F ||
did==0x0090 || did==0x0091 || did==0x0092 || did==0x0093 ||
did==0x0094 || did==0x0095 || did==0x0096 || did==0x0097 ||
did==0x0098 || did==0x0099 || did==0x009A || did==0x009B ||
did==0x009C || did==0x009D || did==0x009E || did==0x009F ||
did==0x00A0 || did==0x00A1 || did==0x00A2 || did==0x00A3 ||
did==0x00A4 || did==0x00A5 || did==0x00A6 || did==0x00A7 ||
did==0x00A8 || did==0x00A9 || did==0x00AA || did==0x00AB ||
did==0x00AC || did==0x00AD || did==0x00AE || did==0x00AF) {
*bus=0; *dev=d; return 0;
}
/* 兜底:所有 Atheros 设备都接受(驱动加载后会校验 chip ID) */
*bus=0; *dev=d;
raw_log("[ath9k.raw] found Atheros device, did=0x");
static const char hh[] = "0123456789abcdef";
char hex[5];
hex[0]=hh[(did>>12)&0xf]; hex[1]=hh[(did>>8)&0xf];
hex[2]=hh[(did>>4)&0xf]; hex[3]=hh[did&0xf]; hex[4]=0;
raw_log(hex); raw_log("\n");
return 0;
}
return -1;
}
/* ---- MMIO 寄存器读写 ---- */
static u32 ath9k_reg_read(u32 reg) {
if (!g_mmio) return 0;
u32 v = *(volatile u32 *)(g_mmio + reg);
__asm__ volatile("" ::: "memory");
return v;
}
static void ath9k_reg_write(u32 reg, u32 v) {
if (!g_mmio) return;
*(volatile u32 *)(g_mmio + reg) = v;
__asm__ volatile("" ::: "memory");
}
static void ath9k_reg_rmw(u32 reg, u32 set, u32 clr) {
u32 v = ath9k_reg_read(reg);
v &= ~clr;
v |= set;
ath9k_reg_write(reg, v);
}
/* ---- EEPROM 读取(AR5416/AR9280 I2C-style EEPROM 接口) ---- */
static u16 ath9k_eeprom_read(u16 addr) {
/* AR5416_EEPROM_CMD: bit0=READ, bit1=BUSY, bit2=RESET */
/* 启动 read:写 cmd=READ | addr<<3 */
ath9k_reg_write(AR_EEPROM_CMD, AR_EEPROM_CMD_RESET);
dkm_delay_us(5);
u32 cmd = AR_EEPROM_CMD_READ | ((u32)(addr & 0x3FF) << 3);
ath9k_reg_write(AR_EEPROM_CMD, cmd);
/* 等待 RDBUSY 清除 (实机: 100ms TSC 超时) */
u64 deadline = dkm_rdtsc() + dkm_tsc_per_ms * 100;
while (dkm_rdtsc() < deadline) {
u32 sts = ath9k_reg_read(AR_EEPROM_STS);
if (!(sts & AR_EEPROM_STS_RDBUSY)) {
if (sts & AR_EEPROM_STS_VALID) {
return (u16)(sts & AR_EEPROM_STS_DATA_M);
}
return 0xffff;
}
dkm_delay_us(1);
}
return 0xffff;
}
/* ---- 软件复位 + RTC 唤醒 ---- */
static int ath9k_reset(void) {
raw_log("[ath9k.raw] reset sequence\n");
/* 1. 强制唤醒(Power-On) */
ath9k_reg_write(AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON | AR_RTC_FORCE_WAKE_INT);
dkm_delay_us(50);
/* 2. 等待 RTC 进入 ON 状态 (实机: 100ms TSC 超时) */
u64 deadline = dkm_rdtsc() + dkm_tsc_per_ms * 100;
while (dkm_rdtsc() < deadline) {
u32 s = ath9k_reg_read(AR_RTC_STATUS);
if ((s & 0x3) == AR_RTC_STATUS_ON) break;
dkm_delay_us(1);
}
/* 3. 全 chip 复位 */
ath9k_reg_write(AR_RC, AR_RC_MAC | AR_RC_BB | AR_RC_RPCU);
dkm_delay_us(100);
ath9k_reg_write(AR_RC, 0);
dkm_delay_us(100);
/* 4. 重新唤醒 */
ath9k_reg_write(AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON | AR_RTC_FORCE_WAKE_INT);
dkm_delay_us(50);
/* 5. 等待 RTC ON (实机: 100ms TSC 超时) */
u32 ok = 0;
u64 deadline2 = dkm_rdtsc() + dkm_tsc_per_ms * 100;
while (dkm_rdtsc() < deadline2) {
u32 s = ath9k_reg_read(AR_RTC_STATUS);
if ((s & 0x3) == AR_RTC_STATUS_ON) { ok = 1; break; }
dkm_delay_us(1);
}
if (!ok) { raw_log("[ath9k.raw] reset: RTC not ON\n"); return -1; }
raw_log("[ath9k.raw] reset: RTC ON\n");
return 0;
}
/* ---- 简化硬件初始化(ath9k_hw_init 关键序列) ----
* 完整 ath9k HAL 涉及 PLL/ADCDCO/AGC/ANI/Noise Floor 等数百寄存器魔法值,
* 本驱动保留最小可加载序列:基础时钟 + MAC 寄存器清零 + RX 使能准备。
* 真实扫描路径在硬件验证后增量完善。
*/
static int ath9k_hw_init(void) {
raw_log("[ath9k.raw] hw_init minimal\n");
/* 关闭 RX/DMA,清 STA_ID1 */
ath9k_reg_write(AR_CR, AR_CR_RXD);
dkm_delay_us(10);
ath9k_reg_write(AR_STA_ID1, 0);
/* 清中断 */
ath9k_reg_write(AR_ISR, 0xFFFFFFFFu);
ath9k_reg_read(AR_ISR_RAC);
/* 写 MAC 地址到 STA_ID0/1(驱动本地缓存) */
u32 mac_lo = (u32)g_mac[0] | ((u32)g_mac[1] << 8) |
((u32)g_mac[2] << 16) | ((u32)g_mac[3] << 24);
u32 mac_hi = (u32)g_mac[4] | ((u32)g_mac[5] << 8);
ath9k_reg_write(AR_STA_ID0, mac_lo);
ath9k_reg_rmw(AR_STA_ID1, (mac_hi & 0xFFFF), 0xFFFFu);
raw_log("[ath9k.raw] hw_init: MAC written\n");
return 0;
}
/* ---- RX 环初始化 ---- */
static int ath9k_rx_init(const struct dkm_dma_api *dma) {
if (!dma || !dma->alloc_pages || !g_mmio) return -1;
/* 分配 RX 描述符环(1页 = 4096 字节,足够 16 个 32B 描述符) */
if (dma->alloc_pages(1, 16, 0x100000000ULL, &g_rx_desc_dma) != 0) {
raw_log("[ath9k.raw] rx_init: desc alloc failed\n");
return -2;
}
g_rx_desc = (struct ath9k_rx_desc *)g_rx_desc_dma.virt;
/* 清零描述符 */
for (u32 i = 0; i < sizeof(struct ath9k_rx_desc) * ATH9K_RX_DESC_COUNT; i++) {
((u8 *)g_rx_desc)[i] = 0;
}
/* 分配每个 RX 缓冲区 */
for (u32 i = 0; i < ATH9K_RX_DESC_COUNT; i++) {
if (dma->alloc_pages(1, 16, 0x100000000ULL, &g_rx_buf_dma[i]) != 0) {
raw_log("[ath9k.raw] rx_init: buf alloc failed\n");
return -3;
}
g_rx_buf[i] = (u8 *)g_rx_buf_dma[i].virt;
/* 填描述符:link 指向下一个,data 指向缓冲区 */
g_rx_desc[i].ds_link = (u32)(g_rx_desc_dma.phys +
(((i + 1) % ATH9K_RX_DESC_COUNT) * sizeof(struct ath9k_rx_desc)));
g_rx_desc[i].ds_data = (u32)g_rx_buf_dma[i].phys;
g_rx_desc[i].ds_ctl0 = ATH9K_RX_BUF_SIZE & ATH9K_RXCTL_BUF_LEN_M;
g_rx_desc[i].ds_ctl1 = ATH9K_RXCTL_INTREQ;
g_rx_desc[i].ds_status0 = 0;
g_rx_desc[i].ds_status1 = 0;
g_rx_desc[i].ds_status2 = 0;
g_rx_desc[i].ds_status3 = 0;
}
__asm__ volatile("" ::: "memory");
raw_log("[ath9k.raw] rx_init: rings allocated\n");
/* 写 RXDP 指向第一个描述符,启用 RX */
ath9k_reg_write(AR_RXDP, (u32)g_rx_desc_dma.phys);
ath9k_reg_write(AR_RXCFG, 0); /* 默认 RX 配置 */
ath9k_reg_write(AR_MIBC, 0); /* 关闭 MIB 计数器,避免中断风暴 */
/* 使能 RXOK/RXERR 中断 */
ath9k_reg_write(AR_IMR, AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN);
/* 启动 RX DMA */
ath9k_reg_write(AR_CR, AR_CR_RXE);
g_rx_head = 0;
g_rx_ready = 1;
raw_log("[ath9k.raw] rx_init: RX enabled\n");
return 0;
}
/* ---- 802.11 beacon IE 解析 ----
* 从 beacon/probe-response 帧中提取 SSID、信道、加密类型。
* 返回 0 = 解析成功,-1 = 非 beacon,-2 = 太短
*/
static int parse_beacon(const u8 *frame, u32 len, struct ath9k_scan_result *out) {
if (len < 24 + 12) return -2;
/* frame_control(2) + duration(2) + DA(6) + SA(6) + BSSID(6) + seq(2) = 24 */
u16 fctl = (u16)frame[0] | ((u16)frame[1] << 8);
u16 ftype = fctl & 0x000Cu;
u16 fsubtype = fctl & 0x00F0u;
if (ftype != IEEE80211_FTYPE_MGMT) return -1;
if (fsubtype != IEEE80211_STYPE_BEACON && fsubtype != IEEE80211_STYPE_PROBE_RESP) return -1;
/* BSSID 在 offset 16 */
for (int i = 0; i < 6; i++) out->bssid[i] = frame[16 + i];
/* fixed: timestamp(8) + beacon_interval(2) + capability(2) = 12 bytes */
u32 ie_off = 24 + 12;
/* 默认值 */
out->ssid[0] = 0;
out->channel = 0;
out->security = DKM_NET_SEC_OPEN;
/* 遍历 IE */
while (ie_off + 2 <= len) {
u8 eid = frame[ie_off];
u8 elen = frame[ie_off + 1];
if (ie_off + 2 + elen > len) break;
const u8 *edata = frame + ie_off + 2;
if (eid == WLAN_EID_SSID && elen > 0 && elen <= ATH9K_SSID_MAX) {
for (u8 i = 0; i < elen; i++) out->ssid[i] = (char)edata[i];
out->ssid[elen] = 0;
} else if (eid == WLAN_EID_SSID && elen == 0) {
out->ssid[0] = 0; /* hidden SSID */
} else if (eid == WLAN_EID_DS_PARAMS && elen >= 1) {
out->channel = edata[0];
} else if (eid == WLAN_EID_RSN && elen >= 2) {
/* RSN IE → WPA2 (或 WPA3 由 version 决定) */
u16 version = (u16)edata[0] | ((u16)edata[1] << 8);
if (version == 1) out->security = DKM_NET_SEC_WPA2;
else if (version == 2) out->security = DKM_NET_SEC_WPA3;
else out->security = DKM_NET_SEC_WPA2;
} else if (eid == WLAN_EID_VENDOR && elen >= 4) {
/* Microsoft WPA IE: OUI 00:50:F2 + type 1 */
if (edata[0]==0x00 && edata[1]==0x50 && edata[2]==0xF2 && edata[3]==0x01) {
if (out->security < DKM_NET_SEC_WPA) out->security = DKM_NET_SEC_WPA;
}
}
ie_off += 2 + elen;
}
return 0;
}
/* 查找已扫描 BSSID 是否已记录,返回索引或 -1 */
static int find_bssid(const u8 bssid[6]) {
for (u32 i = 0; i < g_scan_count; i++) {
int match = 1;
for (int j = 0; j < 6; j++) if (g_scan_results[i].bssid[j] != bssid[j]) { match = 0; break; }
if (match) return (int)i;
}
return -1;
}
/* 处理一个接收到的 802.11 帧(从 RX 缓冲区解析) */
static void ath9k_handle_rx_frame(const u8 *buf, u32 len, i8 rssi) {
struct ath9k_scan_result tmp;
for (int i = 0; i < (int)sizeof(tmp); i++) ((u8 *)&tmp)[i] = 0;
if (parse_beacon(buf, len, &tmp) != 0) return;
/* 跳过隐藏 SSID(长度为 0) */
if (tmp.ssid[0] == 0) return;
tmp.rssi = rssi;
/* 去重:BSSID 已存在则更新 RSSI */
int existing = find_bssid(tmp.bssid);
if (existing >= 0) {
/* 更新 RSSI(取较强值) */
if (rssi > g_scan_results[existing].rssi) g_scan_results[existing].rssi = rssi;
return;
}
if (g_scan_count >= ATH9K_MAX_SCAN_RESULTS) return;
/* 追加 */
g_scan_results[g_scan_count] = tmp;
g_scan_count++;
}
/* 从 RX 环轮询所有已完成描述符 */
static void ath9k_rx_drain(void) {
if (!g_rx_ready) return;
for (u32 i = 0; i < ATH9K_RX_DESC_COUNT; i++) {
u32 idx = g_rx_head;
struct ath9k_rx_desc *d = &g_rx_desc[idx];
__asm__ volatile("" ::: "memory");
if (!(d->ds_status0 & ATH9K_RXSTATUS_DONE)) break;
if (d->ds_status0 & ATH9K_RXSTATUS_OK) {
u32 flen = (d->ds_status0 & ATH9K_RXSTATUS_FRAME_LEN_M) >> ATH9K_RXSTATUS_FRAME_LEN_S;
if (flen > 0 && flen <= ATH9K_RX_BUF_SIZE) {
/* RSSI 在 ds_status2 低 8 位(ath9k convention,负值表示) */
i8 rssi = (i8)(d->ds_status2 & 0xFF);
ath9k_handle_rx_frame(g_rx_buf[idx], flen, rssi);
}
}
/* 重置描述符,归还给硬件 */
d->ds_status0 = 0;
d->ds_status1 = 0;
d->ds_status2 = 0;
d->ds_status3 = 0;
d->ds_ctl0 = ATH9K_RX_BUF_SIZE & ATH9K_RXCTL_BUF_LEN_M;
d->ds_ctl1 = ATH9K_RXCTL_INTREQ;
__asm__ volatile("" ::: "memory");
g_rx_head = (g_rx_head + 1) % ATH9K_RX_DESC_COUNT;
}
}
/* ---- 信道切换(简化版) ----
* 完整 ath9k 信道切换涉及 PLL/RFBUS/ChannelFraction/RFBank 等数十寄存器,
* 本驱动仅写最小序列:PHY RFBUS 请求 + Channel 寄存器占位。
* 真实硬件验证后增量完善。
*/
static void ath9k_set_channel(u8 channel) {
(void)channel;
/* TODO: 完整 ath9k 信道切换序列(参考 ar9002_hw_set_channel) */
/* 触发 RFBUS 请求,等待 grant */
ath9k_reg_write(AR_PHY_RFBUS_REQ, 0x1);
dkm_delay_us(5);
for (u32 i = 0; i < 1000; i++) {
if (ath9k_reg_read(AR_PHY_RFBUS_REQ) & 0x2) break;
dkm_delay_us(1);
}
ath9k_reg_write(AR_PHY_RFBUS_REQ, 0);
dkm_delay_us(50);
}
/* ---- 被动扫描状态机 ----
* 遍历 2.4GHz 信道 1-13,每个信道停留 ~400ms 监听 beacon。
* 完成后 g_scan_count 包含所有发现的 SSID。
*/
static int ath9k_scan_start_impl(void *ctx) {
(void)ctx;
raw_log("[ath9k.raw] scan_start\n");
if (!g_rx_ready) return -1;
g_scanning = 1;
g_scan_count = 0;
for (u32 i = 0; i < ATH9K_MAX_SCAN_RESULTS; i++) {
for (int j = 0; j < (int)sizeof(g_scan_results[i]); j++) {
((u8 *)&g_scan_results[i])[j] = 0;
}
}
for (u32 c = 0; c < ATH9K_CHAN_2G_COUNT; c++) {
u8 channel = (u8)(c + 1);
ath9k_set_channel(channel);
raw_log("[ath9k.raw] scan ch=");
static const char hh[] = "0123456789";
char buf[4]; buf[0]=hh[channel/10]; buf[1]=hh[channel%10]; buf[2]='\n'; buf[3]=0;
raw_log(buf);
/* 在该信道停留 ~400ms,期间轮询 RX 环 */
for (u32 tick = 0; tick < 400; tick++) {
ath9k_rx_drain();
dkm_delay_us(1000);
}
}
g_scanning = 0;
raw_log("[ath9k.raw] scan done, results=");
static const char hh2[] = "0123456789";
char cntbuf[4]; cntbuf[0]=hh2[g_scan_count/10]; cntbuf[1]=hh2[g_scan_count%10]; cntbuf[2]='\n'; cntbuf[3]=0;
raw_log(cntbuf);
return 0;
}
static int ath9k_scan_count_impl(void *ctx) {
(void)ctx;
return (int)g_scan_count;
}
static int ath9k_scan_result_impl(void *ctx, u32 n, struct dkm_net_scan_result *out) {
(void)ctx;
if (!out) return -1;
if (n >= g_scan_count) return -2;
/* 内部 ath9k_scan_result 与 dkm_net_scan_result 布局一致 */
const u8 *src = (const u8 *)&g_scan_results[n];
u8 *dst = (u8 *)out;
for (u32 i = 0; i < sizeof(struct dkm_net_scan_result); i++) dst[i] = src[i];
return 0;
}
static int ath9k_is_wireless_impl(void *ctx) {
(void)ctx;
return 1;
}
/* ath9k 当前不支持 TX(仅扫描) */
static int ath9k_tx_stub(void *ctx, const void *packet, u32 length) {
(void)ctx; (void)packet; (void)length;
return -1;
}
static int ath9k_rx_poll_impl(void *ctx, void *buffer, u32 capacity, u32 *out_length) {
(void)ctx; (void)buffer; (void)capacity;
if (out_length) *out_length = 0;
/* 被动扫描内部消费所有帧,外部 rx_poll 总是返回无数据 */
return 1;
}
static void copy_mac(u8 dst[6], const u8 src[6]) {
for (int i = 0; i < 6; i++) dst[i] = src[i];
}
/* ---- 中断处理(PIC IRQ 路由) ---- */
static int ath9k_irq_handler(u8 irq) {
(void)irq;
if (!g_mmio) return 0;
u32 isr = ath9k_reg_read(AR_ISR_RAC);
if (isr) {
ath9k_reg_write(AR_ISR, isr);
if (isr & (AR_ISR_RXOK | AR_ISR_RXERR | AR_ISR_RXORN)) {
ath9k_rx_drain();
}
}
return 0;
}
/* ---- driver_init ---- */
__attribute__((visibility("default")))
int driver_init(const struct dkm_kernel_api *api,
struct dkm_driver_handle *handle) {
(void)handle;
/* 实机要求: 先校准 TSC, 再使用基于 CPU 频率的延迟 */
dkm_tsc_calibrate();
raw_log("[ath9k.raw] driver_init entered\n");
if (!api || !api->log) return -1;
g_log = api->log;
/* 1. PCI 探测 */
u8 bus, dev;
if (ath9k_find(&bus, &dev) != 0) {
raw_log("[ath9k.raw] no Atheros WiFi device found\n");
return -1;
}
raw_log("[ath9k.raw] Atheros device found\n");
/* 2. 启用 PCI 命令(MEM + Bus Master) */
u32 cmd = pci_read(bus, dev, 0, PCI_COMMAND);
pci_write(bus, dev, 0, PCI_COMMAND, cmd | PCI_CMD_MEM | PCI_CMD_BUSM);
/* 3. 读取 BAR0 */
u32 bar0 = pci_read(bus, dev, 0, PCI_BAR0);
raw_hex("[ath9k.raw] BAR0 raw=", bar0);
if ((bar0 & 0x1) != 0) {
raw_log("[ath9k.raw] BAR0 is IO space, unsupported\n");
return -2;
}
g_bar0_phys = (u64)(bar0 & 0xFFFFFFF0u);
/* 检查是否 64-bit BAR */
if ((bar0 & 0x6) == 0x4) {
u32 bar1 = pci_read(bus, dev, 0, PCI_BAR1);
g_bar0_phys |= ((u64)bar1 << 32);
raw_hex("[ath9k.raw] BAR0 high=", (u64)bar1);
}
raw_hex("[ath9k.raw] BAR0 phys=", g_bar0_phys);
if (g_bar0_phys >= 0x100000000ULL) {
raw_log("[ath9k.raw] BAR0 above 4G, current HHDM cannot map\n");
return -3;
}
/* 4. HHDM 映射 BAR0 */
u64 hhdm = api->hhdm_offset;
raw_hex("[ath9k.raw] HHDM=", hhdm);
g_mmio = (volatile u8 *)(g_bar0_phys + hhdm);
/* 验证 MMIO 可读:读 AR_STA_ID1 */
u32 probe = ath9k_reg_read(AR_STA_ID1);
raw_hex("[ath9k.raw] AR_STA_ID1 probe=", probe);
/* 5. 读取 PCI device ID + IRQ line */
u32 vd = pci_read(bus, dev, 0, PCI_VENDOR_ID);
g_pci_device_id = (u16)(vd >> 16);
g_pci_irq = (u8)pci_read(bus, dev, 0, PCI_IRQ_LINE);
raw_hex("[ath9k.raw] device id=", g_pci_device_id);
raw_hex("[ath9k.raw] irq line=", g_pci_irq);
/* 6. 软件复位 */
if (ath9k_reset() != 0) {
raw_log("[ath9k.raw] reset failed\n");
return -4;
}
/* 7. EEPROM 读取 MAC 地址 */
/* AR5416 EEPROM 偏移:MAC 地址在 word 0x1D-0x1F(6 字节) */
u16 m0 = ath9k_eeprom_read(0x1D);
u16 m1 = ath9k_eeprom_read(0x1E);
u16 m2 = ath9k_eeprom_read(0x1F);
if (m0 == 0xffff && m1 == 0xffff && m2 == 0xffff) {
raw_log("[ath9k.raw] EEPROM MAC all-FF, fallback to all-zero\n");
for (int i = 0; i < 6; i++) g_mac[i] = 0;
} else {
g_mac[0] = (u8)(m0 & 0xFF);
g_mac[1] = (u8)(m0 >> 8);
g_mac[2] = (u8)(m1 & 0xFF);
g_mac[3] = (u8)(m1 >> 8);
g_mac[4] = (u8)(m2 & 0xFF);
g_mac[5] = (u8)(m2 >> 8);
}
{
static const char hh[] = "0123456789abcdef";
char mstr[18];
mstr[0]=hh[(g_mac[0]>>4)&0xf]; mstr[1]=hh[g_mac[0]&0xf]; mstr[2]=':';
mstr[3]=hh[(g_mac[1]>>4)&0xf]; mstr[4]=hh[g_mac[1]&0xf]; mstr[5]=':';
mstr[6]=hh[(g_mac[2]>>4)&0xf]; mstr[7]=hh[g_mac[2]&0xf]; mstr[8]=':';
mstr[9]=hh[(g_mac[3]>>4)&0xf]; mstr[10]=hh[g_mac[3]&0xf]; mstr[11]=':';
mstr[12]=hh[(g_mac[4]>>4)&0xf]; mstr[13]=hh[g_mac[4]&0xf]; mstr[14]=':';
mstr[15]=hh[(g_mac[5]>>4)&0xf]; mstr[16]=hh[g_mac[5]&0xf]; mstr[17]=0;
raw_log("[ath9k.raw] MAC=");
raw_log(mstr);
raw_log("\n");
}
/* 8. 硬件初始化 */
if (ath9k_hw_init() != 0) {
raw_log("[ath9k.raw] hw_init failed\n");
return -5;
}
/* 9. RX 环初始化 */
if (api->dma && api->dma->alloc_pages) {
int rc = ath9k_rx_init(api->dma);
raw_hex("[ath9k.raw] rx_init rc=", (u64)(i8)rc);
if (rc != 0) {
raw_log("[ath9k.raw] RX init failed, scan unavailable\n");
}
} else {
raw_log("[ath9k.raw] no DMA api, scan unavailable\n");
}
/* 10. 注册中断 */
if (api->irq_register && g_pci_irq) {
int rc = api->irq_register(g_pci_irq, ath9k_irq_handler);
raw_hex("[ath9k.raw] irq_register rc=", (u64)(i8)rc);
}
/* 11. 注册 netdev(标记 WIRELESS + RX_READY) */
struct dkm_net_device_desc ndesc;
for (u32 i = 0; i < sizeof(ndesc); i++) ((u8 *)&ndesc)[i] = 0;
static const char devname[] = "ath9k0";
ndesc.name = devname;
copy_mac(ndesc.mac, g_mac);
ndesc.flags = DKM_NET_F_WIRELESS | (g_rx_ready ? DKM_NET_F_RX_READY : 0);
ndesc.ctx = (void *)0; /* ath9k 用全局状态,ctx 不需要 */
ndesc.tx = ath9k_tx_stub;
ndesc.rx_poll = ath9k_rx_poll_impl;
ndesc.scan_start = ath9k_scan_start_impl;
ndesc.scan_count = ath9k_scan_count_impl;
ndesc.scan_result = ath9k_scan_result_impl;
ndesc.is_wireless = ath9k_is_wireless_impl;
if (api->net && api->net->register_device) {
int rc = api->net->register_device(&ndesc);
raw_hex("[ath9k.raw] netdev registered, index=", (u64)rc);
} else {
raw_log("[ath9k.raw] no net api\n");
return -6;
}
/* 12. 启动后台被动扫描(同步执行,阻塞 driver_init 直到扫描完成)
* 注:DSK 加载驱动是顺序的,ath9k 在 stage3 末尾加载,
* 同步扫描会让 stage3 加载多花 ~5s(13 信道 × 400ms)。
* 这是可接受的,因为 FirstInit 在 DSK 之后才运行,能拿到完整扫描结果。
*/
if (g_rx_ready) {
raw_log("[ath9k.raw] starting initial passive scan\n");
ath9k_scan_start_impl(0);
}
raw_log("[ath9k.raw] driver_init done\n");
return 0;
}
__attribute__((visibility("default")))
void driver_exit(struct dkm_driver_handle *handle) {
(void)handle;
if (g_mmio) {
ath9k_reg_write(AR_CR, AR_CR_RXD);
}
g_rx_ready = 0;
g_mmio = 0;
raw_log("[ath9k.raw] driver_exit\n");
}