九阳神功爱喝茶 发表于 2015-01-15 13:25

请教各位一个关于网络通信的问题

本帖最后由 九阳神功爱喝茶 于 2015-01-15 13:27 编辑

小弟现在在导师的要求下,研究无线网卡开源驱动程序Ath9k和MAC层的一些程序,现在遇到些问题,想和大家讨论下,还请多多指教,不甚感激。
1.我老师想根据接收到的ACK信息判断是哪个站点传输过来的,做进一步的研究。我跟踪了代码,结果发现没有接受的时候没处理这个啊。下面是源代码。
/*
* This is the actual Rx frames handler. as it belongs to Rx path it must
* be called with rcu_read_lock protection.
noted by shenlei 2014 12 11 to notice that this is theactual Rx frames handler
*/
static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
                                       struct sk_buff *skb)
{
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_hdr *hdr;
        __le16 fc;
        struct ieee80211_rx_data rx;
        struct ieee80211_sub_if_data *prev;
        struct sta_info *sta, *tmp, *prev_sta;
        int err = 0;

        fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
        memset(&rx, 0, sizeof(rx));
        rx.skb = skb;
        rx.local = local;

        if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
                local->dot11ReceivedFragmentCount++;
//serveral error type noted by shenlei 2014 12 11
        if (ieee80211_is_mgmt(fc)) {
                /* drop frame if too short for header */
                if (skb->len < ieee80211_hdrlen(fc))
                        err = -ENOBUFS;
                else
/**
*      skb_linearize - convert paged skb to linear one
*      @skb: buffer to linarize
*
*      If there is no free memory -ENOMEM is returned, otherwise zero
*      is returned and the old skb data released.
*/
                        err = skb_linearize(skb);
        } else {
                err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
        }

        if (err) {
                dev_kfree_skb(skb);
                return;
        }

        hdr = (struct ieee80211_hdr *)skb->data;
        ieee80211_parse_qos(&rx);
        ieee80211_verify_alignment(&rx);

        if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) ||
                     ieee80211_is_beacon(hdr->frame_control)))
                ieee80211_scan_rx(local, skb);

        if (ieee80211_is_data(fc)) {
                prev_sta = NULL;

                for_each_sta_info(local, hdr->addr2, sta, tmp) {
                        if (!prev_sta) {
                                prev_sta = sta;
                                continue;
                        }

                        rx.sta = prev_sta;
                        rx.sdata = prev_sta->sdata;
                        ieee80211_prepare_and_rx_handle(&rx, skb, false);

                        prev_sta = sta;
                }

                if (prev_sta) {
                        rx.sta = prev_sta;
                        rx.sdata = prev_sta->sdata;

                        if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
                                return;
                        goto out;
                }
        }

        prev = NULL;

        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
                if (!ieee80211_sdata_running(sdata))
                        continue;

                if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
                  sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
                        continue;

                /*
               * frame is destined for this interface, but if it's
               * not also for the previous one we handle that after
               * the loop to avoid copying the SKB once too much
               */

                if (!prev) {
                        prev = sdata;
                        continue;
                }

                rx.sta = sta_info_get_bss(prev, hdr->addr2);
                rx.sdata = prev;
                ieee80211_prepare_and_rx_handle(&rx, skb, false);

                prev = sdata;
        }

        if (prev) {
                rx.sta = sta_info_get_bss(prev, hdr->addr2);
                rx.sdata = prev;

                if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
                        return;
        }

out:
        dev_kfree_skb(skb);
}
根据这部分代码可以清楚地看到接受部分分别处理了一般的数据帧和管理帧Beacon和探测帧ieee80211_is_probe_resp。然后我顺着探测帧接着往下找,仍然没找到ACK,我猜测ACK是做在硬件上的,不知道各位前辈怎么人为的。

第二个问题是:重传次数的确定,关于重传次数我找到两个地方,如下:
第一个是初始化时候的 //noted by shenlei 2015 01 03 retry time rts cts threshold and the coverage_class
        rdev->wiphy.retry_short = 7;
        rdev->wiphy.retry_long = 4;
        rdev->wiphy.frag_threshold = (u32) -1;
        rdev->wiphy.rts_threshold = (u32) -1;
        rdev->wiphy.coverage_class = 0;
第二个是填充ath_tx_info时候关于重传次数这里用的是在函数ath_buf_set_rate中有一个struct ieee80211_tx_rate *rates;
         rates = bf->rates;
然后我跟了下,发现这个速率是在80211层初始化完成的。
然后我老师想禁止重传,我想的是只需要在这儿重信对这个rates赋值不就好了,还是怎么的?

第三个问题是,我很奇怪几乎所有的控制信息都用info结构体保存,然后调用        ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);写入一个ar5416_desc结构体就好了?难道硬件可以识别这么复杂的结构体?我在想怎么不是写入相应的寄存器呢?还是在哪儿我没找到?
struct ar5416_desc {
        u32 ds_link;
        u32 ds_data;
        u32 ds_ctl0;
        u32 ds_ctl1;
        union {
                struct {
                        u32 ctl2;
                        u32 ctl3;
                        u32 ctl4;
                        u32 ctl5;
                        u32 ctl6;
                        u32 ctl7;
                        u32 ctl8;
                        u32 ctl9;
                        u32 ctl10;
                        u32 ctl11;
                        u32 status0;
                        u32 status1;
                        u32 status2;
                        u32 status3;
                        u32 status4;
                        u32 status5;
                        u32 status6;
                        u32 status7;
                        u32 status8;
                        u32 status9;
                } tx;
                struct {
                        u32 status0;
                        u32 status1;
                        u32 status2;
                        u32 status3;
                        u32 status4;
                        u32 status5;
                        u32 status6;
                        u32 status7;
                        u32 status8;
                } rx;
        } u;
} __packed __aligned(4);


static void
ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
{
        struct ar5416_desc *ads = AR5416DESC(ds);
        u32 ctl1, ctl6;

        ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
        ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
        ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
        ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
        ads->ds_txstatus8 = ads->ds_txstatus9 = 0;

        ACCESS_ONCE(ads->ds_link) = i->link;
        //DMA
        ACCESS_ONCE(ads->ds_data) = i->buf_addr;

        ctl1 = i->buf_len | (i->is_last ? 0 : AR_TxMore);
        ctl6 = SM(i->keytype, AR_EncrType);

        if (AR_SREV_9285(ah)) {
                ads->ds_ctl8 = 0;
                ads->ds_ctl9 = 0;
                ads->ds_ctl10 = 0;
                ads->ds_ctl11 = 0;
        }

        if ((i->is_first || i->is_last) &&
          i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) {
                ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0)
                        | set11nTries(i->rates, 1)
                        | set11nTries(i->rates, 2)
                        | set11nTries(i->rates, 3)
                        | (i->dur_update ? AR_DurUpdateEna : 0)
                        | SM(0, AR_BurstDur);

                ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0)
                        | set11nRate(i->rates, 1)
                        | set11nRate(i->rates, 2)
                        | set11nRate(i->rates, 3);
        } else {
                ACCESS_ONCE(ads->ds_ctl2) = 0;
                ACCESS_ONCE(ads->ds_ctl3) = 0;
        }

        if (!i->is_first) {
                ACCESS_ONCE(ads->ds_ctl0) = 0;
                ACCESS_ONCE(ads->ds_ctl1) = ctl1;
                ACCESS_ONCE(ads->ds_ctl6) = ctl6;
                return;
        }

        ctl1 |= (i->keyix != ATH9K_TXKEYIX_INVALID ? SM(i->keyix, AR_DestIdx) : 0)
                | SM(i->type, AR_FrameType)
                | (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
                | (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
                | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);

        switch (i->aggr) {
        case AGGR_BUF_FIRST:
                ctl6 |= SM(i->aggr_len, AR_AggrLen);
                /* fall through */
        case AGGR_BUF_MIDDLE:
                ctl1 |= AR_IsAggr | AR_MoreAggr;
                ctl6 |= SM(i->ndelim, AR_PadDelim);
                break;
        case AGGR_BUF_LAST:
                ctl1 |= AR_IsAggr;
                break;
        case AGGR_BUF_NONE:
                break;
        }

        ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
                | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
                | SM(i->txpower, AR_XmitPower)
                | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
                | (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
                | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
                | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
                | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
                   (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));

        ACCESS_ONCE(ads->ds_ctl1) = ctl1;
        ACCESS_ONCE(ads->ds_ctl6) = ctl6;

        if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST)
                return;

        ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0)
                | set11nPktDurRTSCTS(i->rates, 1);

        ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2)
                | set11nPktDurRTSCTS(i->rates, 3);

        ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0)
                | set11nRateFlags(i->rates, 1)
                | set11nRateFlags(i->rates, 2)
                | set11nRateFlags(i->rates, 3)
                | SM(i->rtscts_rate, AR_RTSCTSRate);
}
还希望大家一起讨论下,谢谢。





页: [1]
查看完整版本: 请教各位一个关于网络通信的问题