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, ®); rt2x00_set_field16(®, 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(®, TXRX_CSR19_TSF_COUNT, 1); rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); reg0 = reg; rt2x00_set_field16(®, 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>