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
...
}

以上有三个比较重要的函数:

  1. RtmpOSIRQRequest() 申请软中断,主要用于收包
  2. mt_wifi_init() 初始化驱动,读取配置文件和 eeprom 就是在这个函数中
  3. 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



参考

无线驱动移植与开发-MTK源码分析