More on the Orinoco + XI-825 + StrongARM platform...
Ben Greear
greearb at candelatech.com
Thu Feb 21 10:46:01 EST 2002
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...
Thanks,
Ben
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 {
#### HERE
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;
}
dev->last_rx = jiffies;
skb->dev = dev;
skb->protocol = eth_type_trans(skb, dev);
skb->ip_summed = CHECKSUM_NONE;
/* 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;
}
>
>
--
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