Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Oct 2011 00:46:48 +0800
From:      Adrian Chadd <adrian@freebsd.org>
To:        Steven Chamberlain <steven@pyro.eu.org>
Cc:        freebsd-net@freebsd.org
Subject:   Re: kern/149643: [rum] device not sending proper beacon frames in ap mode
Message-ID:  <CAJ-Vmonvs=HaoAGvpLw43S4ATmZUi2vaG8JYFhRZAZhfvwcWbQ@mail.gmail.com>
In-Reply-To: <4E9B062A.9050408@pyro.eu.org>
References:  <201110152200.p9FM0QUO044812@freefall.freebsd.org> <CAJ-VmomdNhZd7fEv9CHTBrMaQabO1Xks4Y-gjTMKEe3KNSNPAQ@mail.gmail.com> <4E9A5FB6.7040904@pyro.eu.org> <4E9B062A.9050408@pyro.eu.org>

next in thread | previous in thread | raw e-mail | index | archive | help
I don't think it's the mbuf. It looks like the mbuf allocation is fine.

The linux code in compat-wireless:

* seems to handle endian-ness a bit better;
* does a bunch of different stuff - look at
drivers/net/wireless/rt2x00/rt2500usb.c:

static void rt2500usb_write_beacon(struct queue_entry *entry,
                                   struct txentry_desc *txdesc)

...

        /*
         * Disable beaconing while we are reloading the beacon data,
         * otherwise we might be sending out invalid data.
         */
        rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
        rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
        rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);


(assembles beacon here)

        /*
         * USB devices cannot blindly pass the skb->len as the
         * length of the data to usb_fill_bulk_urb. Pass the skb
         * to the driver to determine what the length should be.
         */
        length = rt2x00dev->ops->lib->get_tx_data_len(entry);

.. which does some fruit:

static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
{
        int length;

        /*
         * The length _must_ be a multiple of 2,
         * but it must _not_ be a multiple of the USB packet size.
         */
        length = roundup(entry->skb->len, 2);
        length += (2 * !(length % entry->queue->usb_maxpacket));

        return length;
}

.. and then it does something with a guard byte, and fiddles with some
more registers:

        /*
         * Second we need to create the guardian byte.
         * We only need a single byte, so lets recycle
         * the 'flags' field we are not using for beacons.
         */
        bcn_priv->guardian_data = 0;
        usb_fill_bulk_urb(bcn_priv->guardian_urb, usb_dev, pipe,
                          &bcn_priv->guardian_data, 1, rt2500usb_beacondone,
                          entry);

        /*
         * Send out the guardian byte.
         */
        usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC);

        /*
         * Enable beaconing again.
         */
        rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
        rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
        reg0 = reg;
        rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
        /*
         * Beacon generation will fail initially.
         * To prevent this we need to change the TXRX_CSR19
         * register several times (reg0 is the same as reg
         * except for TXRX_CSR19_BEACON_GEN, which is 0 in reg0
         * and 1 in reg).
         */
        rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
        rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
        rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
        rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
        rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);

In terms of the setup of the PLCP frame information, that's done in
rt2x00queue.c, in rt2x00queue_create_tx_descriptor_plcp().

It is likely worthwhile comparing the two drivers to see what's
missing/different.

Good luck. :)


Adrian



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-Vmonvs=HaoAGvpLw43S4ATmZUi2vaG8JYFhRZAZhfvwcWbQ>