Lines 1676-1681
Link Here
|
1676 |
struct header_struct hdr; |
1676 |
struct header_struct hdr; |
1677 |
struct ethhdr *eh; |
1677 |
struct ethhdr *eh; |
1678 |
int err; |
1678 |
int err; |
|
|
1679 |
struct ieee802_11_hdr hdr80211; |
1679 |
|
1680 |
|
1680 |
rxfid = hermes_read_regn(hw, RXFID); |
1681 |
rxfid = hermes_read_regn(hw, RXFID); |
1681 |
|
1682 |
|
Lines 1692-1697
Link Here
|
1692 |
|
1693 |
|
1693 |
if (status & HERMES_RXSTAT_ERR) { |
1694 |
if (status & HERMES_RXSTAT_ERR) { |
1694 |
if (status & HERMES_RXSTAT_UNDECRYPTABLE) { |
1695 |
if (status & HERMES_RXSTAT_UNDECRYPTABLE) { |
|
|
1696 |
if (dev->type != ARPHRD_ETHER) goto sniffing; |
1695 |
wstats->discard.code++; |
1697 |
wstats->discard.code++; |
1696 |
DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n", |
1698 |
DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n", |
1697 |
dev->name); |
1699 |
dev->name); |
Lines 1702-1708
Link Here
|
1702 |
stats->rx_errors++; |
1704 |
stats->rx_errors++; |
1703 |
goto drop; |
1705 |
goto drop; |
1704 |
} |
1706 |
} |
1705 |
|
1707 |
sniffing: |
1706 |
/* For now we ignore the 802.11 header completely, assuming |
1708 |
/* For now we ignore the 802.11 header completely, assuming |
1707 |
that the card's firmware has handled anything vital */ |
1709 |
that the card's firmware has handled anything vital */ |
1708 |
|
1710 |
|
Lines 1732-1737
Link Here
|
1732 |
stats->rx_errors++; |
1734 |
stats->rx_errors++; |
1733 |
goto drop; |
1735 |
goto drop; |
1734 |
} |
1736 |
} |
|
|
1737 |
/* Now handle frame based on port# */ |
1738 |
switch( HERMES_RXSTATUS_MACPORT_GET(status) ) |
1739 |
{ |
1740 |
case 0: |
1735 |
|
1741 |
|
1736 |
/* We need space for the packet data itself, plus an ethernet |
1742 |
/* We need space for the packet data itself, plus an ethernet |
1737 |
header, plus 2 bytes so we can align the IP header on a |
1743 |
header, plus 2 bytes so we can align the IP header on a |
Lines 1808-1813
Link Here
|
1808 |
|
1814 |
|
1809 |
return; |
1815 |
return; |
1810 |
|
1816 |
|
|
|
1817 |
case 7: |
1818 |
if ( ! HERMES_RXSTATUS_ISFCSERR(status) ) { |
1819 |
if (hermes_bap_pread(hw, IRQ_BAP, &hdr80211, sizeof(hdr80211), |
1820 |
rxfid, HERMES_RX_80211HDR_OFF)) { |
1821 |
stats->rx_errors++; |
1822 |
} |
1823 |
else { |
1824 |
/* Copy to wlansnif skb */ |
1825 |
orinoco_int_rxmonitor( priv, rxfid, length, &desc, &hdr80211); |
1826 |
} |
1827 |
} else { |
1828 |
printk("Received monitor frame: FCSerr set\n"); |
1829 |
} |
1830 |
break; |
1831 |
|
1832 |
default: |
1833 |
printk("Received frame on unsupported port=%d\n", |
1834 |
HERMES_RXSTATUS_MACPORT_GET(status) ); |
1835 |
break; |
1836 |
} |
1811 |
drop: |
1837 |
drop: |
1812 |
stats->rx_dropped++; |
1838 |
stats->rx_dropped++; |
1813 |
|
1839 |
|
Lines 2450-2455
Link Here
|
2450 |
return err; |
2476 |
return err; |
2451 |
} |
2477 |
} |
2452 |
|
2478 |
|
|
|
2479 |
//#define SET_MAC_ADDRESS |
2480 |
#ifdef SET_MAC_ADDRESS |
2481 |
static int |
2482 |
orinoco_set_mac_address(struct net_device *dev, void *addr) |
2483 |
{ |
2484 |
struct orinoco_private *priv = dev->priv; |
2485 |
struct sockaddr *mac = addr; |
2486 |
|
2487 |
/* Copy the address */ |
2488 |
memcpy(dev->dev_addr, mac->sa_data, WLAN_ADDR_LEN); |
2489 |
|
2490 |
/* Reconfig the beast */ |
2491 |
orinoco_reset(priv); |
2492 |
|
2493 |
return 0; |
2494 |
} |
2495 |
#endif /* SET_MAC_ADDRESS */ |
2496 |
|
2453 |
static void |
2497 |
static void |
2454 |
orinoco_tx_timeout(struct net_device *dev) |
2498 |
orinoco_tx_timeout(struct net_device *dev) |
2455 |
{ |
2499 |
{ |
Lines 3602-3607
Link Here
|
3602 |
return 0; |
3646 |
return 0; |
3603 |
} |
3647 |
} |
3604 |
|
3648 |
|
|
|
3649 |
/*---------------------------------------------------------------- |
3650 |
* orinoco_wlansniff |
3651 |
* |
3652 |
* Start or stop sniffing. |
3653 |
* |
3654 |
* Arguments: |
3655 |
* wlandev wlan device structure |
3656 |
* msgp ptr to msg buffer |
3657 |
* |
3658 |
* Returns: |
3659 |
* 0 success and done |
3660 |
* <0 success, but we're waiting for something to finish. |
3661 |
* >0 an error occurred while handling the message. |
3662 |
* Side effects: |
3663 |
* |
3664 |
* Call context: |
3665 |
* process thread (usually) |
3666 |
* interrupt |
3667 |
----------------------------------------------------------------*/ |
3668 |
static int orinoco_wlansniff(struct net_device *dev, struct iwreq *wrq) |
3669 |
{ |
3670 |
struct orinoco_private *priv = dev->priv; |
3671 |
|
3672 |
hermes_t *hw = &(priv->hw); |
3673 |
hermes_response_t resp; |
3674 |
int result = 0; |
3675 |
uint16_t word; |
3676 |
|
3677 |
int *parms = (int *) wrq->u.name; |
3678 |
int enable = parms[0] > 0; |
3679 |
unsigned long flags; |
3680 |
|
3681 |
orinoco_lock(priv, &flags); |
3682 |
|
3683 |
switch (enable) |
3684 |
{ |
3685 |
case P80211ENUM_truth_false: |
3686 |
/* Confirm that we're in monitor mode */ |
3687 |
if ( dev->type == ARPHRD_ETHER ) { |
3688 |
result = -EFAULT; |
3689 |
} |
3690 |
/* Disable monitor mode */ |
3691 |
word = HERMES_CMD_MONITOR | (HERMES_MONITOR_DISABLE << 8); |
3692 |
result = hermes_docmd_wait(hw, word, 0, &resp); |
3693 |
|
3694 |
if ( result ) break; |
3695 |
|
3696 |
/* Disable port 0 */ |
3697 |
result = hermes_disable_port(hw, 0); |
3698 |
if ( result ) break; |
3699 |
|
3700 |
/* Clear the driver state */ |
3701 |
dev->type = ARPHRD_ETHER; |
3702 |
|
3703 |
/* Restore the wepflags */ //Orinoco doesn't like this |
3704 |
/* |
3705 |
result = hermes_write_wordrec(hw, USER_BAP, |
3706 |
HERMES_RID_CNF_PRISM2_WEP_ON, |
3707 |
priv->presniff_wepflags); |
3708 |
if ( result ) break; |
3709 |
|
3710 |
*/ |
3711 |
/* Set the port to its prior type and enable (if necessary) */ |
3712 |
if (priv->presniff_port_type != 0 ) { |
3713 |
word = priv->presniff_port_type; |
3714 |
result = hermes_write_wordrec(hw, USER_BAP, |
3715 |
HERMES_RID_CNF_PORTTYPE, word); |
3716 |
if ( result ) break; |
3717 |
|
3718 |
/* Enable the port */ |
3719 |
result = hermes_enable_port(hw, 0); |
3720 |
if ( result ) break; |
3721 |
|
3722 |
} |
3723 |
|
3724 |
break; |
3725 |
case P80211ENUM_truth_true: |
3726 |
/* Re-initialize the card before changing channel as advised at |
3727 |
* http://lists.samba.org/pipermail/wireless/2002-June/004491.html |
3728 |
* by Ian Goldberg. Implementation by Pat Swieskowski. |
3729 |
*/ |
3730 |
// __orinoco_down(dev); |
3731 |
hermes_set_irqmask(hw, 0); |
3732 |
hermes_init(hw); |
3733 |
// __orinoco_up(dev); |
3734 |
hermes_set_irqmask(hw, ORINOCO_INTEN); |
3735 |
|
3736 |
// enable re-initialize |
3737 |
// __orinoco_stop_irqs(priv); |
3738 |
// hermes_reset(hw); |
3739 |
// __orinoco_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC | |
3740 |
// HERMES_EV_TX | HERMES_EV_TXEXC | |
3741 |
// HERMES_EV_WTERR | HERMES_EV_INFO | |
3742 |
// HERMES_EV_INFDROP); |
3743 |
|
3744 |
/* Disable the port (if enabled), only check Port 0 */ |
3745 |
if ( hw->port_enabled[0] ) { |
3746 |
/* Save macport 0 state */ |
3747 |
result = hermes_read_wordrec(hw, USER_BAP, |
3748 |
HERMES_RID_CNF_PORTTYPE, |
3749 |
&(priv->presniff_port_type)); |
3750 |
if ( result ) break; |
3751 |
|
3752 |
/* Save the wepflags state */ |
3753 |
result = hermes_read_wordrec(hw, USER_BAP, |
3754 |
HERMES_RID_CNF_PRISM2_WEP_ON, |
3755 |
&(priv->presniff_wepflags)); |
3756 |
if ( result ) break; |
3757 |
result = hermes_disable_port(hw, 0); |
3758 |
if ( result ) break; |
3759 |
|
3760 |
} |
3761 |
else { |
3762 |
priv->presniff_port_type = 0; |
3763 |
} |
3764 |
|
3765 |
/* Set the channel we wish to sniff */ |
3766 |
if (parms[1] > 0 && parms[1] < 15) { |
3767 |
word = parms[1]; |
3768 |
result = hermes_write_wordrec(hw, USER_BAP, |
3769 |
HERMES_RID_CNF_CHANNEL, word); |
3770 |
} else { |
3771 |
result = -EFAULT; |
3772 |
} |
3773 |
|
3774 |
if ( result ) break; |
3775 |
|
3776 |
/* Set the port type to pIbss */ |
3777 |
word = HFA384x_PORTTYPE_IBSS; |
3778 |
result = hermes_write_wordrec(hw, USER_BAP, |
3779 |
HERMES_RID_CNF_PORTTYPE, word); |
3780 |
if ( result ) break; |
3781 |
|
3782 |
/* |
3783 |
if ( (msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && |
3784 |
(msg->keepwepflags.data != P80211ENUM_truth_true)) { |
3785 |
// Set the wepflags for no decryption //Orinoco doesn't like this |
3786 |
word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | |
3787 |
HFA384x_WEPFLAGS_DISABLE_RXCRYPT; |
3788 |
result = hermes_write_wordrec(hw, USER_BAP, |
3789 |
HERMES_RID_CNF_PRISM2_WEP_ON, word); //won't work with the bits above |
3790 |
} |
3791 |
if ( result ) break; |
3792 |
|
3793 |
*/ |
3794 |
/* Enable the port */ |
3795 |
result = hermes_enable_port(hw, 0); |
3796 |
if ( result ) break; |
3797 |
|
3798 |
/* Enable monitor mode */ |
3799 |
word = HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8); |
3800 |
result = hermes_docmd_wait(hw, word, 0, &resp); |
3801 |
if ( result ) break; |
3802 |
|
3803 |
/* Set the driver state */ |
3804 |
/* Do we want the prism2 header? */ |
3805 |
if (parms[0] == 1) |
3806 |
dev->type = ARPHRD_IEEE80211_PRISM; |
3807 |
else |
3808 |
dev->type = ARPHRD_IEEE80211; |
3809 |
break; |
3810 |
default: |
3811 |
result = -EFAULT; |
3812 |
break; |
3813 |
} |
3814 |
orinoco_unlock(priv, &flags); |
3815 |
return result; |
3816 |
|
3817 |
} |
3818 |
|
3605 |
static int |
3819 |
static int |
3606 |
orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
3820 |
orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
3607 |
{ |
3821 |
{ |
Lines 3834-3839
Link Here
|
3834 |
{ SIOCIWFIRSTPRIV + 0x7, 0, |
4048 |
{ SIOCIWFIRSTPRIV + 0x7, 0, |
3835 |
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
4049 |
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
3836 |
"get_ibssport" }, |
4050 |
"get_ibssport" }, |
|
|
4051 |
{ SIOCIWFIRSTPRIV + 0x8, |
4052 |
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, |
4053 |
0, "monitor" }, |
3837 |
{ SIOCIWLASTPRIV, 0, 0, "dump_recs" }, |
4054 |
{ SIOCIWLASTPRIV, 0, 0, "dump_recs" }, |
3838 |
}; |
4055 |
}; |
3839 |
|
4056 |
|
Lines 3928-3933
Link Here
|
3928 |
err = orinoco_ioctl_getibssport(dev, wrq); |
4145 |
err = orinoco_ioctl_getibssport(dev, wrq); |
3929 |
break; |
4146 |
break; |
3930 |
|
4147 |
|
|
|
4148 |
case SIOCIWFIRSTPRIV + 0x8: /* set sniff (monitor) mode */ |
4149 |
DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x8 (monitor)\n", |
4150 |
dev->name); |
4151 |
if (! capable(CAP_NET_ADMIN)) { |
4152 |
err = -EPERM; |
4153 |
break; |
4154 |
} |
4155 |
err = orinoco_wlansniff(dev, wrq); |
4156 |
break; |
4157 |
|
3931 |
case SIOCIWLASTPRIV: |
4158 |
case SIOCIWLASTPRIV: |
3932 |
err = orinoco_debug_dump_recs(priv); |
4159 |
err = orinoco_debug_dump_recs(priv); |
3933 |
if (err) |
4160 |
if (err) |
Lines 4149-4154
Link Here
|
4149 |
dev->tx_timeout = orinoco_tx_timeout; |
4376 |
dev->tx_timeout = orinoco_tx_timeout; |
4150 |
dev->watchdog_timeo = HZ; /* 1 second timeout */ |
4377 |
dev->watchdog_timeo = HZ; /* 1 second timeout */ |
4151 |
dev->get_stats = orinoco_get_stats; |
4378 |
dev->get_stats = orinoco_get_stats; |
|
|
4379 |
#ifdef SET_MAC_ADDRESS |
4380 |
dev->set_mac_address = orinoco_set_mac_address; |
4381 |
#endif /* SET_MAC_ADDRESS */ |
4152 |
dev->get_wireless_stats = orinoco_get_wireless_stats; |
4382 |
dev->get_wireless_stats = orinoco_get_wireless_stats; |
4153 |
dev->do_ioctl = orinoco_ioctl; |
4383 |
dev->do_ioctl = orinoco_ioctl; |
4154 |
dev->change_mtu = orinoco_change_mtu; |
4384 |
dev->change_mtu = orinoco_change_mtu; |
Lines 4173-4178
Link Here
|
4173 |
|
4403 |
|
4174 |
} |
4404 |
} |
4175 |
|
4405 |
|
|
|
4406 |
/*---------------------------------------------------------------- |
4407 |
* orinoco_int_rxmonitor |
4408 |
* |
4409 |
* Helper function for int_rx. Handles monitor frames. |
4410 |
* Note that this function allocates space for the FCS and sets it |
4411 |
* to 0xffffffff. The hfa384x doesn't give us the FCS value but the |
4412 |
* higher layers expect it. 0xffffffff is used as a flag to indicate |
4413 |
* the FCS is bogus. |
4414 |
* |
4415 |
* Arguments: |
4416 |
* dev wlan device structure |
4417 |
* rxfid received FID |
4418 |
* rxdesc rx descriptor read from card in int_rx |
4419 |
* |
4420 |
* Returns: |
4421 |
* nothing |
4422 |
* |
4423 |
* Side effects: |
4424 |
* Allocates an skb and passes it up via the PF_PACKET interface. |
4425 |
* Call context: |
4426 |
* interrupt |
4427 |
----------------------------------------------------------------*/ |
4428 |
void orinoco_int_rxmonitor( struct orinoco_private *dev, uint16_t rxfid, int len, |
4429 |
struct hermes_rx_descriptor *rxdesc, struct ieee802_11_hdr *hdr) |
4430 |
{ |
4431 |
hermes_t *hw = &(dev->hw); |
4432 |
uint32_t hdrlen = 0; |
4433 |
uint32_t datalen = 0; |
4434 |
uint32_t skblen = 0; |
4435 |
p80211msg_lnxind_wlansniffrm_t *msg; |
4436 |
struct net_device_stats *stats = &dev->stats; |
4437 |
|
4438 |
|
4439 |
uint8_t *datap; |
4440 |
uint16_t fc; |
4441 |
struct sk_buff *skb; |
4442 |
|
4443 |
/* Don't forget the status, time, and data_len fields are in host order */ |
4444 |
/* Figure out how big the frame is */ |
4445 |
fc = le16_to_cpu(hdr->frame_ctl); |
4446 |
switch ( WLAN_GET_FC_FTYPE(fc) ) |
4447 |
{ |
4448 |
case WLAN_FTYPE_DATA: |
4449 |
if ( WLAN_GET_FC_TODS(fc) && WLAN_GET_FC_FROMDS(fc) ) { |
4450 |
hdrlen = WLAN_HDR_A4_LEN; |
4451 |
} else { |
4452 |
hdrlen = WLAN_HDR_A3_LEN; |
4453 |
} |
4454 |
datalen = len; |
4455 |
break; |
4456 |
case WLAN_FTYPE_MGMT: |
4457 |
hdrlen = WLAN_HDR_A3_LEN; |
4458 |
datalen = len; |
4459 |
break; |
4460 |
case WLAN_FTYPE_CTL: |
4461 |
switch ( WLAN_GET_FC_FSTYPE(fc) ) |
4462 |
{ |
4463 |
case WLAN_FSTYPE_PSPOLL: |
4464 |
case WLAN_FSTYPE_RTS: |
4465 |
case WLAN_FSTYPE_CFEND: |
4466 |
case WLAN_FSTYPE_CFENDCFACK: |
4467 |
hdrlen = 16; |
4468 |
break; |
4469 |
case WLAN_FSTYPE_CTS: |
4470 |
case WLAN_FSTYPE_ACK: |
4471 |
hdrlen = 10; |
4472 |
break; |
4473 |
} |
4474 |
datalen = 0; |
4475 |
break; |
4476 |
default: |
4477 |
printk("unknown frm: fc=0x%04x\n", fc); |
4478 |
return; |
4479 |
} |
4480 |
|
4481 |
/* Allocate an ind message+framesize skb */ |
4482 |
skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + |
4483 |
hdrlen + datalen; |
4484 |
|
4485 |
/* sanity check the length */ |
4486 |
if ( skblen > |
4487 |
(sizeof(p80211msg_lnxind_wlansniffrm_t) + |
4488 |
WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) { |
4489 |
printk("overlen frm: len=%d\n", |
4490 |
skblen - sizeof(p80211msg_lnxind_wlansniffrm_t)); |
4491 |
} |
4492 |
|
4493 |
if ( (skb = dev_alloc_skb(skblen)) == NULL ) { |
4494 |
printk("alloc_skb failed trying to allocate %d bytes\n", skblen); |
4495 |
return; |
4496 |
} |
4497 |
|
4498 |
/* only prepend the prism header if in the right mode */ |
4499 |
if (dev->ndev->type != ARPHRD_IEEE80211_PRISM) { |
4500 |
skb_put(skb, skblen - sizeof(p80211msg_lnxind_wlansniffrm_t)); |
4501 |
datap = skb->data; |
4502 |
} else { |
4503 |
skb_put(skb, skblen); |
4504 |
datap = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t); |
4505 |
msg = (p80211msg_lnxind_wlansniffrm_t*)skb->data; |
4506 |
|
4507 |
/* Initialize the message members */ |
4508 |
msg->msgcode = DIDmsg_lnxind_wlansniffrm; |
4509 |
msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t); |
4510 |
strcpy(msg->devname, dev->ndev->name); |
4511 |
|
4512 |
msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; |
4513 |
msg->hosttime.status = 0; |
4514 |
msg->hosttime.len = 4; |
4515 |
msg->hosttime.data = jiffies; |
4516 |
|
4517 |
msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; |
4518 |
msg->mactime.status = 0; |
4519 |
msg->mactime.len = 4; |
4520 |
msg->mactime.data = rxdesc->time; |
4521 |
|
4522 |
msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel; |
4523 |
msg->channel.status = P80211ENUM_msgitem_status_no_value; |
4524 |
msg->channel.len = 4; |
4525 |
msg->channel.data = 0; |
4526 |
|
4527 |
msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; |
4528 |
msg->rssi.status = P80211ENUM_msgitem_status_no_value; |
4529 |
msg->rssi.len = 4; |
4530 |
msg->rssi.data = 0; |
4531 |
|
4532 |
msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq; |
4533 |
msg->sq.status = P80211ENUM_msgitem_status_no_value; |
4534 |
msg->sq.len = 4; |
4535 |
msg->sq.data = 0; |
4536 |
|
4537 |
msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal; |
4538 |
msg->signal.status = 0; |
4539 |
msg->signal.len = 4; |
4540 |
msg->signal.data = rxdesc->signal; |
4541 |
|
4542 |
msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise; |
4543 |
msg->noise.status = 0; |
4544 |
msg->noise.len = 4; |
4545 |
msg->noise.data = rxdesc->silence; |
4546 |
|
4547 |
msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate; |
4548 |
msg->rate.status = 0; |
4549 |
msg->rate.len = 4; |
4550 |
msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */ |
4551 |
|
4552 |
msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx; |
4553 |
msg->istx.status = 0; |
4554 |
msg->istx.len = 4; |
4555 |
msg->istx.data = P80211ENUM_truth_false; |
4556 |
|
4557 |
msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; |
4558 |
msg->frmlen.status = 0; |
4559 |
msg->frmlen.len = 4; |
4560 |
msg->frmlen.data = hdrlen + datalen; |
4561 |
} |
4562 |
|
4563 |
/* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */ |
4564 |
memcpy( datap, &(hdr->frame_ctl), hdrlen); |
4565 |
|
4566 |
/* If any, copy the data from the card to the skb */ |
4567 |
if ( datalen > 0 ) |
4568 |
{ |
4569 |
hermes_bap_pread(hw, IRQ_BAP, datap + hdrlen, (datalen+1)&~1, |
4570 |
rxfid, HERMES_RX_DATA_OFF); |
4571 |
|
4572 |
/* check for unencrypted stuff if WEP bit set. */ |
4573 |
if (*(datap+1) & 0x40) // wep set |
4574 |
if ((*(datap+hdrlen) == 0xaa) && (*(datap+hdrlen+1) == 0xaa)) |
4575 |
*(datap+1) &= 0xbf; // clear wep; it's the 802.2 header! |
4576 |
} |
4577 |
|
4578 |
/* pass it up via the PF_PACKET interface */ |
4579 |
{ |
4580 |
skb->dev = dev->ndev; |
4581 |
skb->dev->last_rx = jiffies; |
4582 |
|
4583 |
skb->mac.raw = skb->data ; |
4584 |
skb->ip_summed = CHECKSUM_NONE; |
4585 |
skb->pkt_type = PACKET_OTHERHOST; |
4586 |
skb->protocol = htons(ETH_P_80211_RAW); /* XXX ETH_P_802_2? */ |
4587 |
|
4588 |
stats->rx_packets++; |
4589 |
stats->rx_bytes += skb->len; |
4590 |
|
4591 |
netif_rx(skb); |
4592 |
} |
4593 |
|
4594 |
return; |
4595 |
} |
4596 |
|
4176 |
/********************************************************************/ |
4597 |
/********************************************************************/ |
4177 |
/* Module initialization */ |
4598 |
/* Module initialization */ |
4178 |
/********************************************************************/ |
4599 |
/********************************************************************/ |