您尚未登录。

#1 2021-02-28 00:37:03

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

这个驱动分析起来像捉迷藏一样,本着顺藤摸瓜的思路,发现开了两个tasklet:
1 tasklet_init(&precvpriv->recv_tasklet, (void(*)(unsigned long))usb_recv_tasklet,(unsigned long)padapter);
2 tasklet_init(&pxmitpriv->xmit_tasklet,(void(*)(unsigned long))rtl8188eu_xmit_tasklet,(unsigned long)padapter);
在"ifconfig wlan0 up"开了一个命令线程:rtw_start_drv_threads(padapter).
究竟是如何发送数据的呢?发送任务函数原型是这个:
void rtl8188eu_xmit_tasklet(void *priv)
{
    int ret = _FALSE;
    _adapter *padapter = (_adapter *)priv;
    struct xmit_priv *pxmitpriv = &padapter->xmitpriv;

    while (1) {
        if (RTW_CANNOT_TX(padapter)) {
            RTW_INFO("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
            break;
        }

        if (rtw_xmit_ac_blocked(padapter) == _TRUE)
            break;

        ret = rtl8188eu_xmitframe_complete(padapter, pxmitpriv, NULL);

        if (ret == _FALSE)
            break;
    }

}

而发送数据的函数是包括这个:
s32    rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
{
    return padapter->hal_func.hal_xmit(padapter, pxmitframe);
}
也就是这个:pHalFunc->hal_xmit = &rtl8188eu_hal_xmit;
s32 rtl8188eu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
{    //RTW_INFO("==> %s xmitframe 3 \n", __FUNCTION__);
    return pre_xmitframe(padapter, pxmitframe);
}
还有一串.....
static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
{
    _irqL irqL;
    s32 res;
    struct xmit_buf *pxmitbuf = NULL;
    struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
    struct pkt_attrib *pattrib = &pxmitframe->attrib;
    struct mlme_priv *pmlmepriv = &padapter->mlmepriv;

    _enter_critical_bh(&pxmitpriv->lock, &irqL);

    /* RTW_INFO("==> %s\n",__FUNCTION__); */

    if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0) {
        /* RTW_INFO("enqueue AC(%d)\n",pattrib->priority); */
        goto enqueue;
    }

    if (rtw_xmit_ac_blocked(padapter) == _TRUE)
        goto enqueue;

    if (DEV_STA_LG_NUM(padapter->dvobj))
        goto enqueue;

    pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
    if (pxmitbuf == NULL)
        goto enqueue;

    _exit_critical_bh(&pxmitpriv->lock, &irqL);

    pxmitframe->pxmitbuf = pxmitbuf;
    pxmitframe->buf_addr = pxmitbuf->pbuf;
    pxmitbuf->priv_data = pxmitframe;

    if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
        rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
        rtw_free_xmitframe(pxmitpriv, pxmitframe);
    }

    return _TRUE;

enqueue:
    res = rtw_xmitframe_enqueue(padapter, pxmitframe);
    _exit_critical_bh(&pxmitpriv->lock, &irqL);

    if (res != _SUCCESS) {
        rtw_free_xmitframe(pxmitpriv, pxmitframe);

        pxmitpriv->tx_drop++;
        return _TRUE;
    }

    return _FALSE;
}

static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
{
    s32 res = _SUCCESS;
    /* RTW_INFO("==> %s\n",__FUNCTION__); */

    res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
    if (res == _SUCCESS)
        rtw_dump_xframe(padapter, pxmitframe);//mark
    else
        RTW_INFO("==> %s xmitframe_coalsece failed\n", __FUNCTION__);

    return res;
}

怎么就勾搭上了?
勾搭
#ifdef CONFIG_USB_TX_AGGREGATION
#define IDEA_CONDITION 1    /* check all packets before enqueue */
s32 rtl8188eu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
{
    HAL_DATA_TYPE    *pHalData = GET_HAL_DATA(padapter);
    struct xmit_frame *pxmitframe = NULL;
    struct xmit_frame *pfirstframe = NULL;

    /* aggregate variable */
    struct hw_xmit *phwxmit;
    struct sta_info *psta = NULL;
    struct tx_servq *ptxservq = NULL;

    _irqL irqL;
    _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;

    u32    pbuf;    /* next pkt address */
    u32    pbuf_tail;    /* last pkt tail */
    u32    len;    /* packet length, except TXDESC_SIZE and PKT_OFFSET */

    u32    bulkSize = pHalData->UsbBulkOutSize;
    u8    descCount;
    u32    bulkPtr;

    /* dump frame variable */
    u32 ff_hwaddr;

    _list *sta_plist, *sta_phead;
    u8 single_sta_in_queue = _FALSE;

#ifndef IDEA_CONDITION
    int res = _SUCCESS;
#endif



    /* check xmitbuffer is ok */
    if (pxmitbuf == NULL) {
        pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
        if (pxmitbuf == NULL) {
            /* RTW_INFO("%s #1, connot alloc xmitbuf!!!!\n",__FUNCTION__); */
            return _FALSE;
        }
    }

    /* RTW_INFO("%s =====================================\n",__FUNCTION__); */
    /* 3 1. pick up first frame */
    do {
        rtw_free_xmitframe(pxmitpriv, pxmitframe);

        pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
        if (pxmitframe == NULL) {
            /* no more xmit frame, release xmit buffer */
            /* RTW_INFO("no more xmit frame ,return\n"); */
            rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
            return _FALSE;
        }

#ifndef IDEA_CONDITION
        if (pxmitframe->frame_tag != DATA_FRAMETAG) {
            /*            rtw_free_xmitframe(pxmitpriv, pxmitframe); */
            continue;
        }

        /* TID 0~15 */
        if ((pxmitframe->attrib.priority < 0) ||
            (pxmitframe->attrib.priority > 15)) {
            /*            rtw_free_xmitframe(pxmitpriv, pxmitframe); */
            continue;
        }
#endif
        /* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
        pxmitframe->pxmitbuf = pxmitbuf;
        pxmitframe->buf_addr = pxmitbuf->pbuf;
        pxmitbuf->priv_data = pxmitframe;

        pxmitframe->agg_num = 1; /* alloc xmitframe should assign to 1. */
#ifdef CONFIG_TX_EARLY_MODE
        pxmitframe->pkt_offset = (PACKET_OFFSET_SZ / 8) + 1; /* 2; */ /* first frame of aggregation, reserve one offset for EM info ,another for usb bulk-out block check */
#else
        pxmitframe->pkt_offset = (PACKET_OFFSET_SZ / 8); /* 1; */ /* first frame of aggregation, reserve offset */
#endif

        if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
            RTW_INFO("%s coalesce 1st xmitframe failed\n", __FUNCTION__);
            continue;
        }

        /* always return ndis_packet after rtw_xmitframe_coalesce */
        rtw_os_xmit_complete(padapter, pxmitframe);

        break;
    } while (1);

    /* 3 2. aggregate same priority and same DA(AP or STA) frames */
    pfirstframe = pxmitframe;
    len = rtw_wlan_pkt_size(pfirstframe) + TXDESC_SIZE + (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
    pbuf_tail = len;
    pbuf = _RND8(pbuf_tail);

    /* check pkt amount in one bulk */
    descCount = 0;
    bulkPtr = bulkSize;
    if (pbuf < bulkPtr) {
        descCount++;
        if (descCount == pHalData->UsbTxAggDescNum)
            goto agg_end;
    } else {
        descCount = 0;
        bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; /* round to next bulkSize */
    }

    /* dequeue same priority packet from station tx queue */
    /* psta = pfirstframe->attrib.psta; */
    psta = rtw_get_stainfo(&padapter->stapriv, pfirstframe->attrib.ra);
    if (pfirstframe->attrib.psta != psta)
        RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pfirstframe->attrib.psta, psta);
    if (psta == NULL)
        RTW_INFO("rtw_xmit_classifier: psta == NULL\n");
    if (!(psta->state & _FW_LINKED))
        RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);

    switch (pfirstframe->attrib.priority) {
    case 1:
    case 2:
        ptxservq = &(psta->sta_xmitpriv.bk_q);
        phwxmit = pxmitpriv->hwxmits + 3;
        break;

    case 4:
    case 5:
        ptxservq = &(psta->sta_xmitpriv.vi_q);
        phwxmit = pxmitpriv->hwxmits + 1;
        break;

    case 6:
    case 7:
        ptxservq = &(psta->sta_xmitpriv.vo_q);
        phwxmit = pxmitpriv->hwxmits;
        break;

    case 0:
    case 3:
    default:
        ptxservq = &(psta->sta_xmitpriv.be_q);
        phwxmit = pxmitpriv->hwxmits + 2;
        break;
    }
    /* RTW_INFO("==> pkt_no=%d,pkt_len=%d,len=%d,RND8_LEN=%d,pkt_offset=0x%02x\n", */
    /* pxmitframe->agg_num,pxmitframe->attrib.last_txcmdsz,len,pbuf,pxmitframe->pkt_offset ); */

    _enter_critical_bh(&pxmitpriv->lock, &irqL);

    sta_phead = get_list_head(phwxmit->sta_queue);
    sta_plist = get_next(sta_phead);
    single_sta_in_queue = rtw_end_of_queue_search(sta_phead, get_next(sta_plist));

    xmitframe_phead = get_list_head(&ptxservq->sta_pending);
    xmitframe_plist = get_next(xmitframe_phead);

    while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE) {
        pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
        xmitframe_plist = get_next(xmitframe_plist);

        if (_FAIL == rtw_hal_busagg_qsel_check(padapter, pfirstframe->attrib.qsel, pxmitframe->attrib.qsel))
            break;

        pxmitframe->agg_num = 0; /* not first frame of aggregation */
#ifdef CONFIG_TX_EARLY_MODE
        pxmitframe->pkt_offset = 1;/* not first frame of aggregation,reserve offset for EM Info */
#else
        pxmitframe->pkt_offset = 0; /* not first frame of aggregation, no need to reserve offset */
#endif

        len = rtw_wlan_pkt_size(pxmitframe) + TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);

        if (_RND8(pbuf + len) > MAX_XMITBUF_SZ) {
            /* RTW_INFO("%s....len> MAX_XMITBUF_SZ\n",__FUNCTION__); */
            pxmitframe->agg_num = 1;
            pxmitframe->pkt_offset = 1;
            break;
        }
        rtw_list_delete(&pxmitframe->list);
        ptxservq->qcnt--;
        phwxmit->accnt--;

#ifndef IDEA_CONDITION
        /* suppose only data frames would be in queue */
        if (pxmitframe->frame_tag != DATA_FRAMETAG) {
            rtw_free_xmitframe(pxmitpriv, pxmitframe);
            continue;
        }

        /* TID 0~15 */
        if ((pxmitframe->attrib.priority < 0) ||
            (pxmitframe->attrib.priority > 15)) {
            rtw_free_xmitframe(pxmitpriv, pxmitframe);
            continue;
        }
#endif

        /*        pxmitframe->pxmitbuf = pxmitbuf; */
        pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;

        if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
            RTW_INFO("%s coalesce failed\n", __FUNCTION__);
            rtw_free_xmitframe(pxmitpriv, pxmitframe);
            continue;
        }

        RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority);
        /* always return ndis_packet after rtw_xmitframe_coalesce */
        rtw_os_xmit_complete(padapter, pxmitframe);

        /* (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */
        update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);

        /* don't need xmitframe any more */
        rtw_free_xmitframe(pxmitpriv, pxmitframe);

        /* handle pointer and stop condition */
        pbuf_tail = pbuf + len;
        pbuf = _RND8(pbuf_tail);


        pfirstframe->agg_num++;
#ifdef CONFIG_TX_EARLY_MODE
        pxmitpriv->agg_pkt[pfirstframe->agg_num - 1].offset = _RND8(len);
        pxmitpriv->agg_pkt[pfirstframe->agg_num - 1].pkt_len = pxmitframe->attrib.last_txcmdsz;
#endif
        if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
            break;

        if (pbuf < bulkPtr) {
            descCount++;
            if (descCount == pHalData->UsbTxAggDescNum)
                break;
        } else {
            descCount = 0;
            bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
        }
    } /* end while( aggregate same priority and same DA(AP or STA) frames) */
    if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
        rtw_list_delete(&ptxservq->tx_pending);
    else if (single_sta_in_queue == _FALSE) {
        /* Re-arrange the order of stations in this ac queue to balance the service for these stations */
        rtw_list_delete(&ptxservq->tx_pending);
        rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmit->sta_queue));
    }

    _exit_critical_bh(&pxmitpriv->lock, &irqL);

agg_end:

#ifdef CONFIG_80211N_HT
    if ((pfirstframe->attrib.ether_type != 0x0806) &&
        (pfirstframe->attrib.ether_type != 0x888e) &&
        (pfirstframe->attrib.ether_type != 0x88b4) &&
        (pfirstframe->attrib.dhcp_pkt != 1))
        rtw_issue_addbareq_cmd(padapter, pfirstframe);
#endif /* CONFIG_80211N_HT */
#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
    /* 3 3. update first frame txdesc */
    if ((PACKET_OFFSET_SZ != 0) && ((pbuf_tail % bulkSize) == 0)) {
        /* remove pkt_offset */
        pbuf_tail -= PACKET_OFFSET_SZ;
        pfirstframe->buf_addr += PACKET_OFFSET_SZ;
        pfirstframe->pkt_offset--;
        /* RTW_INFO("$$$$$ buf size equal to USB block size $$$$$$\n"); */
    }
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */

    update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);

#ifdef CONFIG_TX_EARLY_MODE
    /* prepare EM info for first frame, agg_num value start from 1 */
    pxmitpriv->agg_pkt[0].offset = _RND8(pfirstframe->attrib.last_txcmdsz + TXDESC_SIZE + (pfirstframe->pkt_offset * PACKET_OFFSET_SZ));
    pxmitpriv->agg_pkt[0].pkt_len = pfirstframe->attrib.last_txcmdsz;/* get from rtw_xmitframe_coalesce             */

    UpdateEarlyModeInfo8188E(pxmitpriv, pxmitbuf);
#endif

    /* 3 4. write xmit buffer to USB FIFO */
    ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
    /* RTW_INFO("%s ===================================== write port,buf_size(%d)\n",__FUNCTION__,pbuf_tail); */
    /* xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr */

#ifdef CONFIG_XMIT_THREAD_MODE
    pxmitbuf->len = pbuf_tail;
    pxmitbuf->ff_hwaddr = ff_hwaddr;

    if (pfirstframe->attrib.qsel == QSLT_BEACON)
        /* download rsvd page*/
        rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
    else
        enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
#else
    rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
#endif


    /* 3 5. update statisitc */
    pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
    pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);


    rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);

#ifdef CONFIG_XMIT_THREAD_MODE
    if (pfirstframe->attrib.qsel == QSLT_BEACON)
#endif
    rtw_free_xmitframe(pxmitpriv, pfirstframe);

    return _TRUE;
}

#else

s32 rtl8188eu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
{

    struct hw_xmit *phwxmits;
    sint hwentry;
    struct xmit_frame *pxmitframe = NULL;
    int res = _SUCCESS, xcnt = 0;

    phwxmits = pxmitpriv->hwxmits;
    hwentry = pxmitpriv->hwxmit_entry;


    if (pxmitbuf == NULL) {
        pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
        if (!pxmitbuf)
            return _FALSE;
    }


    do {
        pxmitframe =  rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);

        if (pxmitframe) {
            pxmitframe->pxmitbuf = pxmitbuf;

            pxmitframe->buf_addr = pxmitbuf->pbuf;

            pxmitbuf->priv_data = pxmitframe;

            if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
                if (pxmitframe->attrib.priority <= 15) /* TID0~15 */
                    res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
                /*RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority);  */
                rtw_os_xmit_complete(padapter, pxmitframe);/* always return ndis_packet after rtw_xmitframe_coalesce             */
            }

           


            if (res == _SUCCESS){
                rtw_dump_xframe(padapter, pxmitframe);
                RTW_INFO("==> %s xmitframe 1 \n", __FUNCTION__);
            }
            else {
                rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
                rtw_free_xmitframe(pxmitpriv, pxmitframe);
            }

            xcnt++;

        } else {
            rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
            return _FALSE;
        }

        break;

    } while (0/*xcnt < (NR_XMITFRAME >> 3)*/);

    return _TRUE;

}
#endif
勾搭
/* for non-agg data frame or  management frame */
static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
{
    s32 ret = _SUCCESS;
    s32 inner_ret = _SUCCESS;
    int t, sz, w_sz, pull = 0;
    u8 *mem_addr;
    u32 ff_hwaddr;
    struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
    struct pkt_attrib *pattrib = &pxmitframe->attrib;
    struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
    struct security_priv *psecuritypriv = &padapter->securitypriv;
#ifdef CONFIG_80211N_HT
    if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
        (pxmitframe->attrib.ether_type != 0x0806) &&
        (pxmitframe->attrib.ether_type != 0x888e) &&
        (pxmitframe->attrib.ether_type != 0x88b4) &&
        (pxmitframe->attrib.dhcp_pkt != 1))
        rtw_issue_addbareq_cmd(padapter, pxmitframe);
#endif /* CONFIG_80211N_HT */
    mem_addr = pxmitframe->buf_addr;


    for (t = 0; t < pattrib->nr_frags; t++) {
        if (inner_ret != _SUCCESS && ret == _SUCCESS)
            ret = _FAIL;

        if (t != (pattrib->nr_frags - 1)) {

            sz = pxmitpriv->frag_len;
            sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
        } else /* no frag */
            sz = pattrib->last_txcmdsz;

        pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);

        if (pull) {
            mem_addr += PACKET_OFFSET_SZ; /* pull txdesc head */

            /* pxmitbuf->pbuf = mem_addr;             */
            pxmitframe->buf_addr = mem_addr;

            w_sz = sz + TXDESC_SIZE;
        } else
            w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
#ifdef CONFIG_IOL_IOREG_CFG_DBG
        rtw_IOL_cmd_buf_dump(padapter, w_sz, pxmitframe->buf_addr);
#endif
        ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);

#ifdef CONFIG_XMIT_THREAD_MODE
        pxmitbuf->len = w_sz;
        pxmitbuf->ff_hwaddr = ff_hwaddr;

        if (pxmitframe->attrib.qsel == QSLT_BEACON)
            /* download rsvd page*/
            rtw_write_port(padapter, ff_hwaddr, w_sz, (u8 *)pxmitbuf);
        else
            enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
#else
            RTW_INFO("%s:  rtw_write_port size =%d\n", __func__,w_sz);
        inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
#endif

        rtw_count_tx_stats(padapter, pxmitframe, sz);

         RTW_INFO("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority); 

        mem_addr += w_sz;

        mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));

    }

#ifdef CONFIG_XMIT_THREAD_MODE
    if (pxmitframe->attrib.qsel == QSLT_BEACON)
#endif
    rtw_free_xmitframe(pxmitpriv, pxmitframe);

    if (ret != _SUCCESS)
        rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);

    return ret;
}

最近编辑记录 whyabc666 (2021-02-28 15:07:05)

离线

#2 2021-02-28 02:19:10

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

FluxBB bbcode 测试这个dia画图软件不好用,工具栏没和图表合在一起,粘帖函数切换麻烦.

最近编辑记录 whyabc666 (2021-02-28 02:23:57)

离线

#3 2021-02-28 09:37:02

shawn.d
会员
注册时间: 2020-09-12
已发帖子: 132
积分: 128.5

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

终于进入工作状态了,加油!

离线

#4 2021-02-28 10:18:38

wu150
会员
注册时间: 2019-03-30
已发帖子: 57
积分: 56.5

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

我刚好相反,越穷的时候睡的越香,因为没其他想法了

离线

#5 2021-02-28 15:14:01

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

老是会有很多疑问.usb聚合发送是什么新技术?802.3数据转到802.11?监听模式加radiotap是在802.11数据包上?radiotap有没有加到fcs?(从recbuf2recframe看接收状态有记录数据是否丢包,怎么知道recbuf数据出错没有,不是取出数据做CRC和接收到的CRC比较吗?这个函数在哪里?)驱动层的crc校验是哪些函数?

最近编辑记录 whyabc666 (2021-03-01 13:10:34)

离线

#6 2021-02-28 15:16:51

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

从ifconfig wlan0 up 到 _netdev_open 是怎么个流程?

离线

#7 2021-02-28 15:29:29

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

插入驱动的log来看,怎么感觉从module_init(rtw_drv_entry),函数rtw_drv_entry中的usb_register明明在
''rtw_ndev_notifier_register();rtw_inetaddr_notifier_register();''
后面,怎么log却是这样?
RTW: bDriverStopped:True, bSurpriseRemoved:False, bup:0, hw_init_completed:0
RTW: rtw_wiphy_alloc(phy0)
RTW: rtw_wdev_alloc(padapter=c3ea3000)
RTW: rtw_wiphy_register(phy0)
RTW: Register RTW cfg80211 vendor cmd(0x67) interface
RTW: rtw_reg_notifier: NL80211_REGDOM_SET_BY_CORE
RTW: rtw_ndev_init(wlan0) if1 mac_addr=cc:79:cf:94:06:fa
RTW: rtw_ndev_notifier_call(wlan0) state:16
RTW: cfg80211_rtw_get_txpower
RTW: rtw_ndev_notifier_call(wlan0) state:5
usbcore: registered new interface driver 8188eu
RTW: module init ret=0

usb注册主要执行usb探测probe吧, 就是这个".usbdrv.probe = rtw_drv_init, "
static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid)
{
    _adapter *padapter = NULL;
    int status = _FAIL;
    struct dvobj_priv *dvobj;
#ifdef CONFIG_CONCURRENT_MODE
    int i;
#endif

    /* RTW_INFO("+rtw_drv_init\n"); */

    /* step 0. */
    process_spec_devid(pdid);

    /* Initialize dvobj_priv */
    dvobj = usb_dvobj_init(pusb_intf, pdid);
    if (dvobj == NULL) {
        goto exit;
    }

    padapter = rtw_usb_primary_adapter_init(dvobj, pusb_intf);
    if (padapter == NULL) {
        RTW_INFO("rtw_usb_primary_adapter_init Failed!\n");
        goto free_dvobj;
    }

    if (usb_reprobe_switch_usb_mode(padapter) == _TRUE)
        goto free_if_prim;

#ifdef CONFIG_CONCURRENT_MODE
    if (padapter->registrypriv.virtual_iface_num > (CONFIG_IFACE_NUMBER - 1))
        padapter->registrypriv.virtual_iface_num = (CONFIG_IFACE_NUMBER - 1);

    for (i = 0; i < padapter->registrypriv.virtual_iface_num; i++) {
        if (rtw_drv_add_vir_if(padapter, usb_set_intf_ops) == NULL) {
            RTW_INFO("rtw_drv_add_iface failed! (%d)\n", i);
            goto free_if_vir;
        }
    }
#endif

#ifdef CONFIG_GLOBAL_UI_PID
    if (ui_pid[1] != 0) {
        RTW_INFO("ui_pid[1]:%d\n", ui_pid[1]);
        rtw_signal_process(ui_pid[1], SIGUSR2);
    }
#endif

    /* dev_alloc_name && register_netdev */
    if (rtw_os_ndevs_init(dvobj) != _SUCCESS)
        goto free_if_vir;

#ifdef CONFIG_HOSTAPD_MLME
    hostapd_mode_init(padapter);
#endif

#ifdef CONFIG_PLATFORM_RTD2880B
    RTW_INFO("wlan link up\n");
    rtd2885_wlan_netlink_sendMsg("linkup", "8712");
#endif


    status = _SUCCESS;

#if 0 /* not used now */
os_ndevs_deinit:
    if (status != _SUCCESS)
        rtw_os_ndevs_deinit(dvobj);
#endif
free_if_vir:
    if (status != _SUCCESS) {
        #ifdef CONFIG_CONCURRENT_MODE
        rtw_drv_stop_vir_ifaces(dvobj);
        rtw_drv_free_vir_ifaces(dvobj);
        #endif
    }

free_if_prim:
    if (status != _SUCCESS && padapter)
        rtw_usb_primary_adapter_deinit(padapter);

free_dvobj:
    if (status != _SUCCESS)
        usb_dvobj_deinit(pusb_intf);
exit:
    return status == _SUCCESS ? 0 : -ENODEV;
}

既然没注意到这个:
/**
* rtw_os_ndevs_init - Allocate and register OS layer net devices and relating structures for @dvobj
* @dvobj: the dvobj on which this function applies
*
* Returns:
* _SUCCESS or _FAIL
*/
int rtw_os_ndevs_init(struct dvobj_priv *dvobj)
{
    int ret = _FAIL;

    if (rtw_os_ndevs_alloc(dvobj) != _SUCCESS)
        goto exit;

    if (rtw_os_ndevs_register(dvobj) != _SUCCESS)
        goto os_ndevs_free;

    ret = _SUCCESS;

os_ndevs_free:
    if (ret != _SUCCESS)
        rtw_os_ndevs_free(dvobj);
exit:
    return ret;
}

解除疑惑.

最近编辑记录 whyabc666 (2021-02-28 15:38:19)

离线

#8 2021-03-02 21:53:12

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

whyabc666 说:

老是会有很多疑问.usb聚合发送是什么新技术?802.3数据转到802.11?监听模式加radiotap是在802.11数据包上?radiotap有没有加到fcs?(从recvbuf2recvframe看接收状态有记录数据是否丢包,怎么知道recvbuf数据出错没有,不是取出数据做CRC和接收到的CRC比较吗?这个函数在哪里?)驱动层的crc校验是哪些函数?

有个接收状态结构体 struct recv_stat    *prxstat; 属于sk_buff ,( _pkt *pskb;typedef    struct sk_buff    _pkt;) 这个sk_buff的*data就是,
(#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
    pskb = NULL;
    transfer_len = (s32)((struct recv_buf *)ptr)->transfer_len;
    pbuf = ((struct recv_buf *)ptr)->pbuf;
#else
    pskb = (_pkt *)ptr;
    transfer_len = (s32)pskb->len;
    pbuf = pskb->data;
#endif
    prxstat = (struct recv_stat *)pbuf;
    pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;)

crc_err,icr_err是从何而来?从struct rx_pkt_attrib    *pattrib = NULL,(pattrib = &precvframe->u.hdr.attrib)
但是和struct recv_stat    *prxstat有什么关系?
从函数rtl8188e_query_rx_desc_status分析,struct recv_stat report换成了PRXREPORT prxreport,(prxreport = (PRXREPORT)&report).
什么意思呢?结构体数据成员可否相同?反正这个function把接收状态变成了包属性.

最近编辑记录 whyabc666 (2021-03-02 23:09:34)

离线

#9 2021-03-02 23:34:05

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

whyabc666 说:
whyabc666 说:

老是会有很多疑问.usb聚合发送是什么新技术?802.3数据转到802.11?监听模式加radiotap是在802.11数据包上?radiotap有没有加到fcs?(从recvbuf2recvframe看接收状态有记录数据是否丢包,怎么知道recvbuf数据出错没有,不是取出数据做CRC和接收到的CRC比较吗?这个函数在哪里?)驱动层的crc校验是哪些函数?

有个接收状态结构体 struct recv_stat    *prxstat; 属于sk_buff ,( _pkt *pskb;typedef    struct sk_buff    _pkt;) 这个sk_buff的*data就是,
(#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
    pskb = NULL;
    transfer_len = (s32)((struct recv_buf *)ptr)->transfer_len;
    pbuf = ((struct recv_buf *)ptr)->pbuf;
#else
    pskb = (_pkt *)ptr;
    transfer_len = (s32)pskb->len;
    pbuf = pskb->data;
#endif
    prxstat = (struct recv_stat *)pbuf;
    pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;)

crc_err,icr_err是从何而来?从struct rx_pkt_attrib    *pattrib = NULL,(pattrib = &precvframe->u.hdr.attrib)
但是和struct recv_stat    *prxstat有什么关系?
从函数rtl8188e_query_rx_desc_status分析,struct recv_stat report换成了PRXREPORT prxreport,(prxreport = (PRXREPORT)&report).
什么意思呢?结构体数据成员可否相同?反正这个function把接收状态变成了包属性.

从usb读到的precvbuf数据如何变换成sk_buff  *pskb?

离线

#10 2021-03-05 22:15:57

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

一颗赛挺,应垂死听!rtl8188eus驱动在监听模式下通过监听接口注入数据既然没反应?代码这里是干嘛去了哦?
int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev)
{
    _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
    struct    mlme_priv    *pmlmepriv = &(padapter->mlmepriv);
    int ret = 0;

    if (pkt) {
        if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))//mark
            rtw_monitor_xmit_entry((struct sk_buff *)pkt, pnetdev);
#endif
        }
        else {
            rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, pkt->truesize);
            ret = _rtw_xmit_entry(pkt, pnetdev);
        }

    }

    return ret;
}
监听模式的数据应该走的这条路线啊
rtw_monitor_xmit_entry->dump_mgntframe->rtw_hal_mgnt_xmit->hal_func.mgnt_xmit(pHalFunc->mgnt_xmit = &rtl8188eu_mgnt_xmit)
s32 rtl8188eu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
{
    RTW_INFO("==> %s xmitframe 2\n", __FUNCTION__);
    return rtw_dump_xframe(padapter, pmgntframe);
}
既然没有log出来?

最近编辑记录 whyabc666 (2021-03-06 00:37:28)

离线

#11 2021-03-08 19:43:08

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

搞驱动是喝原厂的剩汤?一万一月都没有?

离线

#12 2021-03-08 20:05:32

whyabc666
会员
注册时间: 2019-12-12
已发帖子: 364
积分: 358

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

whyabc666 说:
whyabc666 说:

老是会有很多疑问.usb聚合发送是什么新技术?802.3数据转到802.11?监听模式加radiotap是在802.11数据包上?radiotap有没有加到fcs?(从recvbuf2recvframe看接收状态有记录数据是否丢包,怎么知道recvbuf数据出错没有,不是取出数据做CRC和接收到的CRC比较吗?这个函数在哪里?)驱动层的crc校验是哪些函数?

有个接收状态结构体 struct recv_stat    *prxstat; 属于sk_buff ,( _pkt *pskb;typedef    struct sk_buff    _pkt;) 这个sk_buff的*data就是,
(#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
    pskb = NULL;
    transfer_len = (s32)((struct recv_buf *)ptr)->transfer_len;
    pbuf = ((struct recv_buf *)ptr)->pbuf;
#else
    pskb = (_pkt *)ptr;
    transfer_len = (s32)pskb->len;
    pbuf = pskb->data;
#endif
    prxstat = (struct recv_stat *)pbuf;
    pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;)

crc_err,icr_err是从何而来?从struct rx_pkt_attrib    *pattrib = NULL,(pattrib = &precvframe->u.hdr.attrib)
但是和struct recv_stat    *prxstat有什么关系?
从函数rtl8188e_query_rx_desc_status分析,struct recv_stat report换成了PRXREPORT prxreport,(prxreport = (PRXREPORT)&report).
什么意思呢?结构体数据成员可否相同?反正这个function把接收状态变成了包属性.

继续深挖,从USB端口读到的接收的数据为啥就带接收状态各种标志?是USB网卡固件加上去的吗?

离线

#13 2021-03-27 12:00:35

拍打323
会员
注册时间: 2021-02-19
已发帖子: 30
积分: 28.5

Re: 穷得不敢睡觉,梳理一下rtl8188eus驱动源码.

白嫖一篇牛逼的技术分析帖。慢慢消化。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn