MT76xx 无线驱动源码分析
ifconfig ra0 up
这句命令调用的是 pNetDevOps->ndo_open,也就是 main_virtual_if_open
/*
* ========================================================================
* Routine Description:
* Open raxx interface.
* ========================================================================
*/
int main_virtual_if_open(struct net_device *net_dev)
{
if (VIRTUAL_IF_INIT(pAd, net_dev) != 0)
return -1;
if (VIRTUAL_IF_UP(pAd, net_dev) != 0) // up interface
return -1;
/* 开启网络队列 */
netif_start_queue(net_dev);
netif_carrier_on(net_dev);
netif_wake_queue(net_dev);
return 0;
}
VIRTUAL_IF_UP 通过 ioctl 调用 mt_wifi_open
int mt_wifi_open(VOID *dev)
{
...
RtmpOSIRQRequest(net_dev); // request irq
/* Init IRQ parameters stored in pAd */
/* rtmp_irq_init(pAd); */
RTMP_DRIVER_IRQ_INIT(pAd);
/* Chip & other init */
if (mt_wifi_init(pAd, mac, hostname) == FALSE) // init 驱动
goto err;
RT28xx_MBSS_Init(pAd, net_dev); // Multi BSS
RTMPDrvOpen(pAd); // 开启驱动底层,硬件相关的 txrx
...
}
以上有三个比较重要的函数:
- RtmpOSIRQRequest() 申请软中断,主要用于收包
- mt_wifi_init() 初始化驱动,读取配置文件和 eeprom 就是在这个函数中
- RTMPDrvOpen() 开启中断,打开硬件开关等
ra0 收包
之前在 ra0 open 的时候我们讲到调用 RtmpOSIRQRequest() 注册了软中断
request_irq(pci_dev->irq, rt2860_interrupt, SA_SHIRQ, (net_dev)->name, (net_dev));
硬件(ASIC)收到包之后会触发软中断处理函数 rt2860_interrupt()
IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance)
{
struct net_device *net_dev = (struct net_device *) dev_instance;
VOID *pAd = NULL;
GET_PAD_FROM_NET_DEV(pAd, net_dev);
isr_handle(pAd); // 中断处理函数,mt7615 里面是:RTMPHandleInterrupt(pAd);
return IRQ_HANDLED;
}
isr_handle() 最终调用 mtd_isr
static VOID mtd_isr(RTMP_ADAPTER *pAd)
{
/* Inital the Interrupt source. */
UINT32 IntSource = 0x00000000L; // 中断源,根据这个来调用各种 kernel tasklet
if (IntSource & MT_INT_TX_DONE) { // 发包完成中断
if ((pci_hif->intDisableMask & (IntSource & MT_INT_TX_DONE)) == 0)
tm_ops->schedule_task(pAd, TX_DONE_TASK);
pci_hif->IntPending |= (IntSource & MT_INT_TX_DONE);
tp_dbg->IsrTxCnt++;
}
if (IntSource & MT_INT_RX_DATA) { // 收包中断
if (!(IntSource & MT_INT_RX_DLY))
IntSource &= ~MT_INT_RX_DATA;
else
pci_hif->IntPending |= MT_INT_RX_DATA;
tp_dbg->IsrRxCnt++;
}
if (IntSource & MT_INT_RX_CMD) {
if (!(IntSource & MT_INT_RX_DLY))
IntSource &= ~MT_INT_RX_CMD;
else
pci_hif->IntPending |= MT_INT_RX_CMD;
tp_dbg->IsrRx1Cnt++;
}
if (IntSource & MT_INT_RX_DLY) {
if ((pci_hif->intDisableMask & MT_INT_RX_DLY) == 0)
tm_ops->schedule_task(pAd, TR_DONE_TASK);
pci_hif->IntPending |= MT_INT_RX_DLY;
tp_dbg->IsrRxDlyCnt++;
}
if (IntSource & MT_INT_SUBSYS_INT_STS) {
if ((pci_hif->intDisableMask & (IntSource & MT_INT_SUBSYS_INT_STS)) == 0)
tm_ops->schedule_task(pAd, SUBSYS_INT_TASK); // schedule rx 的 tasklet
}
HIF_IO_WRITE32(pAd->hdev_ctrl, MT_INT_SOURCE_CSR, IntSource); // 关闭接收中断
mt_int_disable(pAd, IntSource);
}
而 rx_done_task 在 RtmpNetTaskInit 中已经定义了 tasklet 的function:rx_done_tasklet,调用 rtmp_rx_done_handle
BOOLEAN rtmp_rx_done_handle(RTMP_ADAPTER *pAd)
{
os_zero_mem(&rxblk, sizeof(RX_BLK));
pRxBlk = &rxblk;
asic_get_pkt_from_rx_resource(pAd, &bReschedule, &RxPending, HIF_RX_IDX0); // 从 rxring 中拿取报文
/* 报文处理 */
rx_packet_process(pAd, pRxPacket, pRxBlk);
}
NDIS_STATUS rx_packet_process(
RTMP_ADAPTER *pAd,
PNDIS_PACKET pRxPacket,
RX_BLK *pRxBlk)
{
switch (FC->Type) {
case FC_TYPE_DATA: // 数据帧
if (RX_BLK_TEST_FLAG(pRxBlk, fRX_HDR_TRANS))
dev_rx_802_3_data_frm(pAd, pRxBlk);
else
dev_rx_802_11_data_frm(pAd, pRxBlk);
break;
case FC_TYPE_MGMT: // 管理帧
dev_rx_mgmt_frm(pAd, pRxBlk);
break;
case FC_TYPE_CNTL: // 控制帧
dev_rx_ctrl_frm(pAd, pRxBlk);
break;
default:
RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
break;
}
return NDIS_STATUS_SUCCESS;
}
dev_rx_data_frm 函数的调用栈如下,到达 netif_rx 就到了网络协议栈了,这里没考虑 ampdu,forward 等情况,只是简单列下调用过程
dev_rx_data_frm
---rx_data_frm_announce
---Indicate_Legacy_Packet
---Announce_or_Forward_802_3_Packet
---announce_802_3_packet
---RtmpOsPktRcvHandle
---netif_rx
附录
module_init(rt_pci_init_module)
rt_pci_init_module()
pci_module_init(&rt_pci_driver);
probe: rt_pci_probe,
rt_pci_probe()
/*PCIDevInit============================================== */
pci_enable_device()
pci_set_dma_mask()
pci_request_regions()
pci_set_master()
os_alloc_mem()
/*NetDevInit============================================== */
RtmpPhyNetDevInit() // 主要对网络设备初始化,对设备的operation进行赋值
pNetDevHook->open = MainVirtualIF_open; // ifconfig ra0 up
MainVirtualIF_open()
VIRTUAL_IF_UP()
.mt_wifi_open
RtmpOSIRQRequest(net_dev); // 开启硬件中断处理函数,主要 RX
request_irq()
mt_wifi_init() /*rename from rt28xx_init*/ // 主要设置 mac 以及数据帧处理定时器初始化, 读取配置文件和EEPROM就是在这个函数中
rtmp_sys_init()
RtmpMgmtTaskInit() // 注册管理帧kernel work
rtmp_cfg_init() // 读取配置文件.dat
RTMPReadParametersHook() // 读取参数
os_file_open()
os_file_read()
RTMPSetProfileParameters() // 根据 profile 设置参数
RTMPGetKeyParameter("MacAddress", tmpbuf, 25, pBuffer, TRUE) //Get key parameter. 以后自己若要实现 profile 文件读写,可以参考此函数的实现
RT_CfgSetMacAddress(pAd, tmpbuf,0) // 读取 profile 设置 MAC,但是default profile 没有 MAC 条目。应该是通过 bin 设置的。不过这里也实验成功,进一步说明这里的优先级比别处高,因为使用了这里的配置
os_file_close()
WfInit()
WfTopInit()
WfHifInit()
WfMcuInit()
WfMcuSysInit()
RtmpNetTaskInit() // 注册数据包kernel work
WfEPROMInit()
WfEPROMSysInit()
NICReadEEPROMParameters() // 读取EEPROM // 读取AP_PROFILE_PATH_RBUS 中的配置参数,可以看作是hostapd.conf
WfMacInit()
WfPhyInit()
RT28xx_MBSS_Init() // 无线设置相关
RT28xx_WDS_Init()
RTMP_DRIVER_CFG80211_START()
RTMPDrvOpen() // 开启驱动底层,硬件相关的 tx rx,开启终端,打开硬件
pNetDevHook->xmit = rt28xx_send_packets; // 无线发包
rt28xx_send_packets()
rt28xx_packet_xmit()
RTMPSendPackets()
wdev_tx_pkts()
wdev->tx_pkt_allowed // = ApAllowToSendPacket() 检查目的mac是否是关联的设备,如果是就允许,不是就不允许
wdev->tx_pkt_handle // = APSendPacket()
RTMPDeQueuePacket()
_RTMPDeQueuePacket()
pTxBlk->wdev->wdev_hard_tx // = APHardTransmit // 发包函数
pci_set_drvdata()
/*All done, it's time to register the net device to linux kernel. */
RtmpOSNetDevAttach()
RtmpPhyNetDevInit()
pNetDevHook->xmit = rt28xx_send_packets; // 发送
rt28xx_send_packets()
rt28xx_packet_xmit()
RTMPSendPackets()
wdev_tx_pkts()
rt2860_interrupt() // 接收,中断触发
RTMPHandleInterrupt()
rx_done_task()
rtmp_rx_done_handle()
rx_packet_process()
dev_rx_data_frm()
rx_data_frm_announce()
Indicate_Legacy_Packet()
Announce_or_Forward_802_3_Packet()
announce_802_3_packet()
RtmpOsPktRcvHandle()
netif_rx()
/* Load param (MT7615_EEPROM.bin) */
RTMP_COM_IoctlHandle()
RTMPInitPCIeDevice()
pci_read_config_word(pci_dev, pConfig->ConfigDeviceID, &device_id); // 读配置空间中的 device_id=0x7615,pConfig->ConfigDeviceID:redister offset, Value: 16-bit value
rtmp_rlt_pci_chip_cfg()
DriverOwn()
HIF_IO_WRITE32(pAd, HIF_SYS_REV, 1); /* Write any value to HIF_SYS_REV clear FW own */
RtmpRaDevCtrlInit()
RtmpChipOpsRegister()
RtmpChipOpsHook()
WfSysPreInit()
mt7615_init()
mt7615_chipCap_init() // bin
mt7615_get_default_bin_image_file()
mt_chip_bcn_parameter_init(pAd); // configure beacon related parameters
UINT16 BcnMaxHwSize; /* hardware maximum beacon size */
/* Load MCU firmware (WIFI_RAM_CODE_MT7615.bin) */
WfInit()
WfHifInit()
WfMcuInit()
WfMcuHwInit()
NICLoadFirmware()
ad->chipOps.loadFirmware(ad); // == AndesMTLoadFw()
AndesMTLoadFw()
AndesMTLoadFwMethodFwDlRing()
MtCmdFwScatters()
MtCmdFwScatter() // 一次最多发 4K。PCIe Spec
pr_info("\033[31m###\033[0m %s\n", __FUNCTION__);
参考:https://blog.csdn.net/sky619351517/article/details/89280347
cat embedded/conf/RT2860.dat
Default
CountryRegion=5 // 2.4G国家区域,如果 eeprom 里面已经有了,此处不起作用。地区不同,使用的信道范围也不同,5:1-14 all active scan
CountryRegionABand=7 // 5G 国家区域,36、40、44、48、……、161、165
CountryCode=US // 设置国家码
DBDC_MODE=0
BssidNum=1
SSID= // 设置 AP SSID
SSID1=RTDEV_AP5g_123
SSID2=
SSID3=
SSID4=
SSID5=
SSID6=
SSID7=
SSID8=
WirelessMode=14 // 设置 WLAN 模式,14=11a/an/ac mixed 5G band only(Only 11ac chipset support)
FixedTxMode=HT // 设置固定TX模式为CCK或OFDM或HT
EthConvertMode=
TxRate=0
Channel=157 // 设置 WiFi 信道
BasicRate=15 // 设置 OFDM 基本速率
BeaconPeriod=100 // 设置 Beacon 周期,100ms,范围:20~1024
DtimPeriod=1 // 设置 DTIM 周期,范围:1~5
TxPower=100 // 设置发射功率百分比,范围:0~100
DisableOLBC=0 // 设置启用或禁用 OLBC,0:disable,1:enable
BGProtection=0 // 设置 11b、11g 保护,0:disable,1:always on,2:always off
TxAntenna=
RxAntenna=
TxPreamble=1 // 设置启用或禁用 TxPreamble
RTSThreshold=2347 // 设置 RTS 门限
FragThreshold=2346 // 设置 Fragment 门限
TxBurst=1 // 设置启用或禁用TxBurst模式
PktAggregate=1 // 设置启用或禁用包聚合
AutoProvisionEn=0
FreqDelta=0
TurboRate=0
WmmCapable=1 // WMM参数 // WMM :Wi-Fi Multimedia // Enable or disable WMM QoS function(WMM无线多媒体,开启后提高其传输性能)
APAifsn=3;7;1;1 // 仲裁帧间隙数:AC_BE(尽力而为);AC_BK(背景);AC_VI(视频);AC_VO(语音)
APCwmin=4;4;3;2 // 最小竞争窗口指数
APCwmax=6;10;4;3 // 最大竞争窗口指数
APTxop=0;0;94;47 // AP Transmit Opportunity configuration (unit: 32μs)(传输机会限制)
APACM=0;0;0;0 // AP Admission Control Mandatory configuration(强制配置)
BSSAifsn=3;7;2;2 // STA arbitration interframe space number configuration
BSSCwmin=4;4;3;2 // STA contention window minimum (exponent) configuration
BSSCwmax=10;10;4;3 // STA contention window maximum (exponent) configuration
BSSTxop=0;0;94;47 // STA Transmit Opportunity configuration (unit: 32μs)
BSSACM=0;0;0;0 // STA Admission Control Mandatory configuration
AckPolicy=0;0;0;0 // Acknowledgement policy configuration(ACK策略)
APSDCapable=1 // WMM Automatic Power Save Delivery (APSD) function configuration(自动省电认证协议)
DLSCapable=1
NoForwarding=00 // 设置启用或禁用在相同 BSSID 内 STA 之间的包不转发
NoForwardingBTNBSSID=0 // 设置启用或禁用在每个 BSSID 接口间不转发
HideSSID=0 // 设置启用或禁用 SSID
ShortSlot=1 // 设置启用或禁用 short slot time
AutoChannelSelect=0 // 设置自动信道选择算法
IEEE8021X=0
IEEE80211H=1
CarrierDetect=0
ITxBfEn=1
PreAntSwitch=1
PhyRateLimit=0
DebugFlags=0
ETxBfEnCond=1
ITxBfTimeout=0
ETxBfTimeout=0
ETxBfNoncompress=0
ETxBfIncapable=0
FineAGC=0
StreamMode=0
StreamModeMac0=
StreamModeMac1=
StreamModeMac2=
StreamModeMac3=
CSPeriod=6
RDRegion=CE
StationKeepAlive=0
DfsCalibration=0
DfsEnable=1
DfsLowerLimit=0
DfsUpperLimit=0
DfsOutdoor=0
SymRoundFromCfg=0
BusyIdleFromCfg=0
DfsRssiHighFromCfg=0
DfsRssiLowFromCfg=0
DFSParamFromConfig=0
FCCParamCh0=
FCCParamCh1=
FCCParamCh2=
FCCParamCh3=
CEParamCh0=
CEParamCh1=
CEParamCh2=
CEParamCh3=
JAPParamCh0=
JAPParamCh1=
JAPParamCh2=
JAPParamCh3=
JAPW53ParamCh0=
JAPW53ParamCh1=
JAPW53ParamCh2=
JAPW53ParamCh3=
FixDfsLimit=0
LongPulseRadarTh=0
AvgRssiReq=0
DFS_R66=0
BlockCh=
GreenAP=0
PreAuth=0 // Encryption 参数。Enable or disable WPA2 pre-authentication mode
AuthMode=OPEN // WLAN security authentication mode
EncrypType=NONE // WLAN security encryption type
WapiPsk1=
WapiPsk2=
WapiPsk3=
WapiPsk4=
WapiPsk5=
WapiPsk6=
WapiPsk7=
WapiPsk8=
WapiPskType=
Wapiifname=
WapiAsCertPath=
WapiUserCertPath=
WapiAsIpAddr=
WapiAsPort=
BssidNum=1
RekeyMethod=DISABLE // Configuration of rekey method for WPA/WPA2
RekeyInterval=3600 // Rekey interval configuration for WPA/WPA2
PMKCachePeriod=10 // PMK cache life time configuration for WPA/WPA2
MeshAutoLink=0
MeshAuthMode=
MeshEncrypType=
MeshDefaultkey=0
MeshWEPKEY=
MeshWPAKEY=
MeshId=
WPAPSK= // WLAN security password for TKIP/AES. 8~63 ASCII characters
WPAPSK1=12345678
WPAPSK2=
WPAPSK3=
WPAPSK4=
WPAPSK5=
WPAPSK6=
WPAPSK7=
WPAPSK8=
DefaultKeyID=1 // Default key ID (WEP only)
Key1Type=0 // key 1 type. 0: Hexadecimal,1: ASCII
Key1Str1=
Key1Str2=
Key1Str3=
Key1Str4=
Key1Str5=
Key1Str6=
Key1Str7=
Key1Str8=
Key2Type=0
Key2Str1=
Key2Str2=
Key2Str3=
Key2Str4=
Key2Str5=
Key2Str6=
Key2Str7=
Key2Str8=
Key3Type=0
Key3Str1=
Key3Str2=
Key3Str3=
Key3Str4=
Key3Str5=
Key3Str6=
Key3Str7=
Key3Str8=
Key4Type=0
Key4Str1=
Key4Str2=
Key4Str3=
Key4Str4=
Key4Str5=
Key4Str6=
Key4Str7=
Key4Str8=
HSCounter=0
HT_HTC=1 // HT:High Throuthput,802.11n有两种频宽模式:HT20和HT40。 enable or disable Support the HT control field;0: disable,1: enable
HT_RDG=1 // Enable or disable HT Reverse Direction Grant
HT_LinkAdapt=0 // enable or disable HT Link Adaptation Control
HT_OpMode=0 // HT operation mode. 0: HT mixed mode,1: HT Greenfield mode
HT_MpduDensity=5 // Minimum separation of MPDUs in an A-MPDU. 5: 4 μs
HT_EXTCHA=1
HT_BW=1 // HT channel bandwidth configuration. 0: 20 MHz,1: 20/40 MHz
HT_AutoBA=1 // Enable or disable auto build Block Ack section with peer
HT_BADecline=0
HT_AMSDU=1 // Enable or disable AMSDU section
HT_BAWinSize=64 // Block Ack window size. 1~64
HT_GI=1 // HT Guard interval support // 保护间隔 // 0: Long guard interval,1: short guard interval
HT_STBC=1
HT_MCS=33 // WLAN Modulation and Coding Scheme (MCS) (调制与编码策略). 33: Auto Rate Adaption, recommended
HT_TxStream=4
HT_RxStream=4
HT_PROTECT=1
HT_DisallowTKIP=1
HT_BSSCoexistence=0
HT_LDPC=1
GreenAP=0
VHT_BW=1 // VHT:Very High Throughput(极高吞吐量). // 11ac chipset only
VHT_Sec80_Channel=0
VHT_STBC=1 // Enable or disable 11ac STBC (space-time block coding)
VHT_SGI=1
VHT_BW_SIGNAL=0 // Enable or disable 11ac bandwidth signaling
VHT_LDPC=1 // Enable or disable LDPC on received packets with 11ac MCS
G_BAND_256QAM=0
WscConfMode=0
WscConfStatus=2
WCNTest=0
AccessPolicy0=0 // 设置 ACL表 的访问策略
AccessControlList0=
AccessPolicy1=0
AccessControlList1=
AccessPolicy2=0
AccessControlList2=
AccessPolicy3=0
AccessControlList3=
AccessPolicy4=0
AccessControlList4=
AccessPolicy5=0
AccessControlList5=
AccessPolicy6=0
AccessControlList6=
AccessPolicy7=0
AccessControlList7=
WdsEnable=0 // WDS参数 // WDS function configuration. 0:Disable WDS function
WdsPhyMode=
WdsEncrypType=NONE // The option includes NONE, WEP, TKIP and AES.
WdsList= // WDS peer MAC address configuration
Wds0Key= // 8 ~ 63 ASCII characters (eg: 12345678) for TKIP or AES
Wds1Key=
Wds2Key=
Wds3Key=
RADIUS_Server=0 // Remote Authentication Dial In User Service(远程用户拨号认证服务 // Configure radius server IP address. RADIUS_Server=192.168.2.3
RADIUS_Port=1812 // Port
RADIUS_Key1= // Key
RADIUS_Key2=
RADIUS_Key3=
RADIUS_Key4=
RADIUS_Key5=
RADIUS_Key6=
RADIUS_Key7=
RADIUS_Key8=
RADIUS_Acct_Server=
RADIUS_Acct_Port=1813
RADIUS_Acct_Key=
own_ip_addr=192.168.1.254
Ethifname=
EAPifname=br0
PreAuthifname=br0
session_timeout_interval=0
idle_timeout_interval=0
WiFiTest=0
TGnWifiTest=0
ApCliEnable=0
ApCliSsid=
ApCliBssid=
ApCliAuthMode=
ApCliEncrypType=
ApCliWPAPSK=
ApCliDefaultKeyID=0
ApCliKey1Type=0
ApCliKey1Str=
ApCliKey2Type=0
ApCliKey2Str=
ApCliKey3Type=0
ApCliKey3Str=
ApCliKey4Type=0
ApCliKey4Str=
MACRepeaterEn=0
MACRepeaterOuiMode=0
EfuseBufferMode=0
E2pAccessMode=1
PMFMFPC=1 // PMF参数 // Protected Management Frame(受保护的管理帧) // 802.11w标准,可防御特别针对WLAN管理帧的攻击,保证无线通信的安全性和稳定性。 // Enable or disable Protection Management Frame Capable
PMFMFPR=0 // Enable or disable Protection Management Frame Required
PMFSHA256=0 // Enable or disable use SHA256 for Encryption.
RadioOn=1
BW_Enable=0
BW_Root=0
BW_Priority=
BW_Guarantee_Rate=
BW_Maximum_Rate=
BW_Guarantee_Airtime_Ratio=
BW_Maximum_Airtime_Ratio=
SSID=
WPAPSK=
Key1Str=
Key2Str=
Key3Str=
Key4Str=
BandSteering=0
WscManufacturer= // WPS 参数 // Wi-Fi Protected Setup(WiFi保护设置) // WPS manufacturer string(制造商)
WscModelName= // WPS Mode name string
WscDeviceName= // WPS Device name string
WscModelNumber // WPS Device model number string