Linux SDIO WIFI Marvell8801/Marvell88w8801(八) --- Marvell Linux Wi-Fi driver 对接芯片上行下行接口介绍
代码工程的GITHUB连接:点进进入GITHUB仓库https://github.com/sj15712795029/stm32f1_marvell88w8801_marvell8801_wifi1.Linux SDIO WIFI Marvell8801/Marvell88w8801(一) — 代码及文档介绍2. Linux SDIO WIFI Marvell8801/Marvell88w8...
代码工程的GITHUB连接:点进进入GITHUB仓库
https://github.com/sj15712795029/stm32f1_marvell88w8801_marvell8801_wifi
1.Linux SDIO WIFI Marvell8801/Marvell88w8801(一) — 代码及文档介绍
2. Linux SDIO WIFI Marvell8801/Marvell88w8801(二) — Marvell88w8801驱动编译
3. Linux SDIO WIFI Marvell8801/Marvell88w8801(三) — Linux驱动以及组件的使用
4. Linux SDIO WIFI Marvell8801/Marvell88w8801(四) — Linux Wi-Fi架构
5. Linux SDIO WIFI Marvell8801/Marvell88w8801(五) — Linux SDIO API介绍
6. Linux SDIO WIFI Marvell8801/Marvell88w8801(六) — Marvell Linux Wi-Fi driver介绍-WIFI插入卡槽内发生的事情
7. Linux SDIO WIFI Marvell8801/Marvell88w8801(七) — Marvell Linux Wi-Fi driver初始化
8. Linux SDIO WIFI Marvell8801/Marvell88w8801(八) — Marvell Linux Wi-Fi driver 对接芯片上行下行接口介绍
关于本章内容介绍如下:
1)CMD/CMD RESPONSE上行下行接口介绍
2)EVENT上行接口介绍
3)DATA上行下行接口介绍
首先在说一遍,这里所说的上行接口是指host<-card,也就是芯片到驱动的接口,下行接口是指host->card,也就是驱动下发给芯片的接口
上行接口一共就是三类:cmd/cmd response,event,data
Cmd/cmd response是指驱动发送给芯片的命令,response是指在cmd发送完毕后,芯片会送给驱动的命令响应。所以cmd算是下行的,cmd response算是上行的
Event是芯片给驱动的事件,此处仅仅是上行接口
Data就是我们的tcp/ip数据,所以data是双向的,既有上行,也有下行
下面我们对这三类一一介绍
1. CMD/CMD RESPONSE上行下行接口介绍
说到cmd/cmd response首先先介绍下cmd node的概念,在init的时候会做一个初始化的动作,在这个wlan_alloc_cmd_buffer函数中
整个cmd node的结构体如下
看一下关键的初始化代码
申请15个cmd node,并且把这个15个cmd node的pmbuf申请2K的空间,整个执行完毕后是这样
然后来看这个
里面的实现对于我们初始化来说,基本上执行运行了这个util_enqueue_list_tail函数
这个函数的实现是
我们可以画一个图来表示下最终的结果
整个cmd init完成了,那么我们就来直接看cmd的下行接口吧
Cmd的处理方式为:
我们就拿初始化的时候HostCmd_CMD_802_11_MAC_ADDRESS这个命令为例吧
实现的逻辑是:
Step 1:从cmd_free_q中unlink一个cmd node
Step2:init cmd node,主要做的事情为把申请的2K的buffer赋值给cmd_buffer,并且填充上cmd type & len
Step 3:把cmd_prt赋值cmd_buffer->pbuf偏移data_offset(此处为4,也就是预留SDIO type & len)
Step4:组封包
也就是调用这个wlan_ops_sta_prepare_cmd函数中的case
Step5:插入到cmd_pending_q中
到了这边其实就有两个处理方式了,虽然方式不同,但是最终都是通过mlan_main_process函数中的wlan_exec_next_cmd(pmadapter)写到芯片中,两种方式为:
1)在init的时候直接主动调用mlan_main_process进行判断写入
2)IOCTL/WEXT/CFG80211是通过唤醒work queue来调用mlan_main_process
第二种方式为:queue_work(priv->phandle->workqueue, &priv->phandle->main_work);唤醒
Work queue,最终调用到woal_main_work_queue,然后里面调用mlan_main_process,其中这部分牵扯到kernel的工作队列,相关内容自行补充,不管用那种方式,假设我们已经执行到mlan_main_process,那么他是怎么处理的呢
Step6:通过wlan_exec_next_cmd调用到wlan_dnld_cmd_to_fw这个
其中wlan_dnld_cmd_to_fw这个函数的里面处理有几方面
1)wlan_sdio_host_to_card->wlan_write_data_sync->pcb->moal_write_data_sync通过SDIO的CMD53把命令写下去
2)启动一个timer来检测在timeout内有没有得到cmd response,如果得到cmd response就stop这个timer,如果没有得到cmd response就会调用wlan_cmd_timeout_func来做处理
好了,cmd的处理大致流程就这样了,如果想看详细的都在代码中,自行查看,下面来看看cmd response的处理
在这个首先先说一下upload的中断,此中断时有数据到芯片我们host就会受到此中断,那么我们就做相应的处理,同样按照step说下cmd response的处理步骤
Step 1:收到cmd response的时候,首先发生SDIO中断,调用woal_sdio_interrupt处理
Step 2: wlan_interrupt会把func1的64个寄存器读出来,其中中断寄存器是0x03 HOST_INT_STATUS_REG
Step 3: 最终交于mlan_main_process处理
Step 4: 首先处理中断,wlan_process_int_status
Step 4: 读出数据 wlan_process_int_status->wlan_sdio_card_to_host_mp_aggr->
wlan_sdio_card_to_host->
pcb->moal_read_data_sync(pmadapter->pmoal_handle, pmbuf, ioport,0);
Step 5: 解析收到的数据wlan_decode_rx_packet
Step6: 发现是cmd response,就做如下处理
Step 7: 继续执行mlan_main_process,发现cmd_resp_received被置位
Step 8: wlan_process_cmdresp 会做以下几方面的处理
1)stop发送cmd时候的timer
2)Cmd resp处理pmpriv->ops.process_cmdresp(pmpriv, cmdresp_no, resp,pioctl_buf);
也就是最终调用了wlan_ops_sta_process_cmdresp
3)把cmd node 重新插入到cmd free q中
2 EVENT上行接口介绍
Event的处理其实和cmd response类似,前5个步骤类似,那么我们就直接从第6个步骤不同的做介绍
Step 6: case 是event,把event_received置为TRUE
Step 7: 同样交于mlan_main_process,发现event_received被置位
Step 8: 交于priv->ops.process_event(priv);处理,其实是调用wlan_ops_sta_process_event处理。
3 DATA上行下行接口介绍
这个小节来说明下上行和下行接口,首先说下上行行接口,因为和上面的cmd reponse/event的前5个步骤类似,从第六个步骤说起
Step 6:把rx数据放到rx_data_queue中,并且把data_received之为TRUE
Step 7: 在mlan_main_process中做判断,然后自己生成一个driver自定义的event:MLAN_EVENT_ID_DRV_DEFER_RX_WORK
Step 8:在moal_recv_event处理case MLAN_EVENT_ID_DRV_DEFER_RX_WORK唤醒rx queue
Step 9:在rx queue的处理函数中处理mlan_rx_process
Step 10: 在mlan_rx_process中从rx_data_queue中dequeue出来收到的数据,调用wlan_handle_rx_packet函数做处理
Step 11: 交于priv->ops.process_rx_packet做处理,事实上就是
wlan_ops_sta_process_rx_packet函数处理
注意到了wlan_ops_sta_process_rx_packet这个里面难点开始出现,会分不同的case做处理
802.11有reorder的东西存在,关于reorder你暂且这样理解吧,比如一个封包被拆分为几个包,此处假设被分为序列为1~10,但是wifi传输过程中,并不是按照顺序传输过来的,可能顺序被打乱,所以需要重新组包,再上传给tcp/ip,但是reorder只针对于单播包,对于多播,组播不做处理,所以有了step12
Step 12: 如果不是单播包,直接上传给tcp/ip
整个过程为wlan_process_rx_packet->pmadapter->callbacks.moal_recv_packet->
moal_recv_packet->netif_rx或者netif_rx_ni
其中netif_rx或者netif_rx_ni就是Linux tcp/ip的接收
另外,说起单播封包处理就比较复杂,牵扯到reorder,de-aggregation的动作在里面,但是最终都调用wlan_process_rx_packet进行处理,下面我贴出marvell文档针对rx data的部分
处理流程图为:
下面来看下下行数据吧
Step 1: Linux的tcp/ip会调用woal_hard_start_xmit把tcp/ip数据os层发送给wifi driver
Step 2: 然后woal_hard_start_xmi会调用mlan_send_packet,然后唤醒main work queue
Step 3: 然后mlan_main_process调用wlan_wmm_process_tx
Step 4: 然后wlan_dequeue_tx_packet调用wlan_send_single_packet(此处不考虑aggre封包)
Step 5: 调用wlan_process_tx-》wlan_sdio_host_to_card-》wlan_host_to_card_mp_aggr-》wlan_write_data_sync使用SDIO cmd53写到芯片中,TX部分其实还有一些复杂的特定,想深入的可以自行研究下,我们列出Marvell文档的tx 流程图
更多推荐
所有评论(0)