More on the Orinoco + XI-825 + StrongARM platform...

Ben Greear greearb at candelatech.com
Thu Feb 21 15:57:11 EST 2002


Here is some more debugging.  It appears that protocol is not
correct, or maybe I'm just not printing it out correctly???
Code that generated it is below...

Packet received, hdr:
00 60 b3 69 56 67 00 02 2d 0b 27 a0 00 5c aa aa
03 00 00 00 08 00
Packet received, data_len: 82  data_off: 68 skb->len: 96 skb->data:
skb->protocol: 0x8  skb->data addr: c14be4d2
00 60 b3 69 56 67 00 02 2d 0b 27 a0 08 00 45 00
00 54 00 00 40 00 40 01 e0 41 ac 01 01 01 ac 01
01 64 08 00 79 9d 10 0c 02 00 99 71 74 3c 65 a5
0e 00 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15
16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35

After eth_type_trans, data_len: 82  data_off: 68 skb->len: 82 skb->data:
skb->protocol: 0x8  skb->data addr: c14be4e0
45 00 00 54 00 00 40 00 40 01 e0 41 ac 01 01 01
ac 01 01 64 08 00 79 9d 10 0c 02 00 99 71 74 3c
65 a5 0e 00 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13
14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33
34 35


static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw)
{
	struct net_device *dev = &priv->ndev;
	struct net_device_stats *stats = &priv->stats;
	struct iw_statistics *wstats = &priv->wstats;
	struct sk_buff *skb = NULL;
	u16 rxfid, status;
	int length, data_len, data_off;
	char *p;
	struct hermes_rx_descriptor desc;
	struct header_struct hdr;
	struct ethhdr *eh;
	int err;

	rxfid = hermes_read_regn(hw, RXFID);
	DEBUG(3, "__orinoco_ev_rx(): RXFID=0x%04x\n", rxfid);

	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
			       rxfid, 0);
	if (err) {
		printk(KERN_ERR "%s: error %d reading Rx descriptor. "
		       "Frame dropped.\n", dev->name, err);
		stats->rx_errors++;
		goto drop;
	}

	status = le16_to_cpu(desc.status);
	
	if (status & HERMES_RXSTAT_ERR) {
		if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
			wstats->discard.code++;
			DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
			       dev->name);
		} else {
			stats->rx_crc_errors++;
			DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
		}
		stats->rx_errors++;
		goto drop;
	}

	/* For now we ignore the 802.11 header completely, assuming
            that the card's firmware has handled anything vital */

	err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),
			       rxfid, HERMES_802_3_OFFSET);
	if (err) {
		printk(KERN_ERR "%s: error %d reading frame header. "
		       "Frame dropped.\n", dev->name, err);
		stats->rx_errors++;
		goto drop;
	}
         else {
            int i = 0;
            const unsigned char* dbg = (const unsigned char*)(&hdr);
            printk("Packet received, hdr:\n");
            for (i = 0; i<(sizeof(hdr)); i++) {
               printk("%02hx ", (unsigned short)(dbg[i]));
               if (((i + 1) % 16) == 0) {
                  printk("\n");
               }
            }
            printk("\n");
         }

	length = ntohs(hdr.len);
	
	/* Sanity check */
	if (length > MAX_FRAME_SIZE) {
		printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
		       dev->name, length);
		stats->rx_length_errors++;
		stats->rx_errors++;
		goto drop;
	}

	/* We need space for the packet data itself, plus an ethernet
	   header, plus 2 bytes so we can align the IP header on a
	   32bit boundary, plus 1 byte so we can read in odd length
	   packets from the card, which has an IO granularity of 16
	   bits */
	skb = dev_alloc_skb(length+ETH_HLEN+2+1);
	if (!skb) {
		printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
		       dev->name);
		stats->rx_dropped++;
		goto drop;
	}

	skb_reserve(skb, 2); /* This way the IP header is aligned */

	/* Handle decapsulation
	 * In most cases, the firmware tell us about SNAP frames.
	 * For some reason, the SNAP frames sent by LinkSys APs
	 * are not properly recognised by most firmwares.
	 * So, check ourselves (note : only 3 bytes out of 6).
	 */
	if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
	   ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
	   is_snap(&hdr)) {
		/* These indicate a SNAP within 802.2 LLC within
		   802.11 frame which we'll need to de-encapsulate to
		   the original EthernetII frame. */

		/* Remove SNAP header, reconstruct EthernetII frame */
		data_len = length - ENCAPS_OVERHEAD;
		data_off = HERMES_802_3_OFFSET + sizeof(hdr);

		eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);

		memcpy(eh, &hdr, 2 * ETH_ALEN);
		eh->h_proto = hdr.ethertype;
	} else {
		/* All other cases indicate a genuine 802.3 frame.  No
		   decapsulation needed.  We just throw the whole
		   thing in, and hope the protocol layer can deal with
		   it as 802.3 */
		data_len = length;
		data_off = HERMES_802_3_OFFSET;
		/* FIXME: we re-read from the card data we already read here */
	}

	p = skb_put(skb, data_len);
	err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
			       rxfid, data_off);
	if (err) {
		printk(KERN_ERR "%s: error %d reading frame header. "
		       "Frame dropped.\n", dev->name, err);
		stats->rx_errors++;
		goto drop;
	}

         if (1) {
            int i = 0;
            const unsigned char* dbg = (const unsigned char*)(skb->data);
            printk("Packet received, data_len: %i  data_off: %i skb->len: %i skb->data:\n",
                   data_len, data_off, skb->len);
            printk("skb->protocol: 0x%x  skb->data addr: %p\n", skb->protocol, skb->data);
            for (i = 0; i<skb->len; i++) {
               printk("%02hx ", (unsigned short)(dbg[i]));
               if (((i + 1) % 16) == 0) {
                  printk("\n");
               }
            }
            printk("\n");
         }

	dev->last_rx = jiffies;
	skb->dev = dev;
	skb->protocol = eth_type_trans(skb, dev);
	skb->ip_summed = CHECKSUM_NONE;

         if (1) {
            int i = 0;
            const unsigned char* dbg = (const unsigned char*)(skb->data);
            printk("After eth_type_trans, data_len: %i  data_off: %i skb->len: %i skb->data:\n",
                   data_len, data_off, skb->len);
            printk("skb->protocol: 0x%x  skb->data addr: %p\n", skb->protocol, skb->data);
            for (i = 0; i<skb->len; i++) {
               printk("%02hx ", (unsigned short)(dbg[i]));
               if (((i + 1) % 16) == 0) {
                  printk("\n");
               }
            }
            printk("\n");
         }


	/* Process the wireless stats if needed */
	orinoco_stat_gather(dev, skb, &desc);

	/* Pass the packet to the networking stack */
	netif_rx(skb);
	stats->rx_packets++;
	stats->rx_bytes += length;

	return;

  drop:	
	if (skb)
		dev_kfree_skb_irq(skb);
	return;
}



David Gibson wrote:

> On Wed, Feb 20, 2002 at 04:46:01PM -0700, Ben Greear wrote:
> 
>>
>>David Gibson wrote:
>>
>>
>>>On Wed, Feb 20, 2002 at 09:05:50AM -0700, Ben Greear wrote:
>>>
>>>
>>>>Here is what the received packet header looks like with
>>>>the latest 'testing' driver.  It looks like the 08 06
>>>>should be where the 00 44 is, if I understand things correctly.
>>>>
>>>>Packet received, hdr:
>>>>00 60 b3 69 56 67 00 02 2d 0b 27 a0 00 44 aa aa
>>>>03 00 00 00 08 06
>>>>
>>>>
>>>How are you capturing this packet - this the extra stuff here is an
>>>802.2 header.  Over the air, 802.11 always has an encapsulated 802.2
>>>header, but the driver is supposed to convert to Ethernet-II frames.
>>>
>>
>>I put printk statements in the driver, see below.  Can you tell if
>>the header is correct at this stage?  If so, I can add more debugging
>>farther up the stack to see where it gets lost/corrupted, etc...
>>
> 
> Ok, your printk()s are before the decapsulation logic, so you're
> seeing the packet's 802.2 header, and the fake 802.3 header that the
> card generates.  Given that, it looks correct.
> 
> 


-- 
Ben Greear <greearb at candelatech.com>       <Ben_Greear AT excite.com>
President of Candela Technologies Inc      http://www.candelatech.com
ScryMUD:  http://scry.wanfear.com     http://scry.wanfear.com/~greear






More information about the wireless mailing list