Added support for the sniff indication interface.
This commit is contained in:
parent
681dea73b2
commit
9c3206d536
|
@ -1112,10 +1112,10 @@ typedef struct hfa384x_rx_frame
|
|||
/*-- MAC rx descriptor (hfa384x byte order) --*/
|
||||
UINT16 status __WLAN_ATTRIB_PACK__;
|
||||
UINT32 time __WLAN_ATTRIB_PACK__;
|
||||
UINT8 signal __WLAN_ATTRIB_PACK__;
|
||||
UINT8 silence __WLAN_ATTRIB_PACK__;
|
||||
UINT8 rx_flow __WLAN_ATTRIB_PACK__;
|
||||
UINT8 signal __WLAN_ATTRIB_PACK__;
|
||||
UINT8 rate __WLAN_ATTRIB_PACK__;
|
||||
UINT8 rx_flow __WLAN_ATTRIB_PACK__;
|
||||
UINT16 reserved1 __WLAN_ATTRIB_PACK__;
|
||||
UINT16 reserved2 __WLAN_ATTRIB_PACK__;
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include <wlan/p80211conv.h>
|
||||
#include <wlan/p80211msg.h>
|
||||
#include <wlan/p80211netdev.h>
|
||||
#include <wlan/p80211req.h>
|
||||
#include <wlan/p80211metadef.h>
|
||||
#include <wlan/p80211metastruct.h>
|
||||
#include <prism2/hfa384x.h>
|
||||
|
@ -134,6 +135,7 @@ static void prism2sta_int_info(wlandevice_t *wlandev);
|
|||
static void prism2sta_int_txexc(wlandevice_t *wlandev);
|
||||
static void prism2sta_int_tx(wlandevice_t *wlandev);
|
||||
static void prism2sta_int_rx(wlandevice_t *wlandev);
|
||||
static void prism2sta_int_rxmonitor( wlandevice_t *wlandev, UINT16 rxfid, hfa384x_rx_frame_t *rxdesc);
|
||||
static void prism2sta_int_alloc(wlandevice_t *wlandev);
|
||||
|
||||
static void prism2sta_inf_handover(wlandevice_t *wlandev, void *buf);
|
||||
|
@ -1162,46 +1164,6 @@ void prism2sta_int_rx(wlandevice_t *wlandev)
|
|||
rxdesc.time = hfa384x2host32(rxdesc.time);
|
||||
rxdesc.data_len = hfa384x2host16(rxdesc.data_len);
|
||||
|
||||
/* Allocate the buffer, note CRC (aka FCS). This function assumes */
|
||||
/* there needs to be space for one */
|
||||
pb = p80211pb_alloc_p80211(NULL,
|
||||
rxdesc.data_len + WLAN_HDR_A3_LEN + WLAN_CRC_LEN);
|
||||
if ( pb == NULL ) {
|
||||
WLAN_LOG_DEBUG0(1, "pballoc failed.\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Copy the 802.11 hdr to the buffer */
|
||||
result = hfa384x_copy_from_bap(hw, hw->bap, rxfid,
|
||||
HFA384x_RX_80211HDR_OFF, pb->p80211_hdr, WLAN_HDR_A3_LEN);
|
||||
if ( result ) {
|
||||
WLAN_LOG_DEBUG4(1,
|
||||
"copy_from_bap(0x%04x, %d, %d) failed, result=%d\n",
|
||||
rxfid,
|
||||
HFA384x_RX_80211HDR_OFF,
|
||||
WLAN_HDR_A3_LEN,
|
||||
result);
|
||||
p80211pb_free(pb);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Copy the payload data to the buffer */
|
||||
result = hfa384x_copy_from_bap(hw, hw->bap, rxfid,
|
||||
HFA384x_RX_DATA_OFF, pb->p80211_payload, rxdesc.data_len);
|
||||
if ( result ) {
|
||||
WLAN_LOG_DEBUG4(1,
|
||||
"copy_from_bap(0x%04x, %d, %d) failed, result=%d\n",
|
||||
rxfid,
|
||||
HFA384x_RX_DATA_OFF,
|
||||
rxdesc.data_len,
|
||||
result);
|
||||
p80211pb_free(pb);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Set the length */
|
||||
pb->p80211frmlen = WLAN_HDR_A3_LEN + rxdesc.data_len + WLAN_CRC_LEN;
|
||||
|
||||
#if 0
|
||||
printk(KERN_DEBUG"rxf(%d): ",rxlen);
|
||||
for (i=0; i<pb->p80211frmlen; i++) {
|
||||
|
@ -1214,23 +1176,60 @@ printk("\n");
|
|||
switch( HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) )
|
||||
{
|
||||
case 0:
|
||||
/* Allocate the buffer, note CRC (aka FCS). pballoc */
|
||||
/* assumes there needs to be space for one */
|
||||
pb = p80211pb_alloc_p80211(NULL,
|
||||
rxdesc.data_len + WLAN_HDR_A3_LEN + WLAN_CRC_LEN);
|
||||
if ( pb == NULL ) {
|
||||
WLAN_LOG_DEBUG0(1, "pballoc failed.\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Copy the 802.11 hdr to the buffer */
|
||||
result = hfa384x_copy_from_bap(hw, hw->bap, rxfid,
|
||||
HFA384x_RX_80211HDR_OFF, pb->p80211_hdr, WLAN_HDR_A3_LEN);
|
||||
if ( result ) {
|
||||
WLAN_LOG_DEBUG4(1,
|
||||
"copy_from_bap(0x%04x, %d, %d) failed, result=%d\n",
|
||||
rxfid,
|
||||
HFA384x_RX_80211HDR_OFF,
|
||||
WLAN_HDR_A3_LEN,
|
||||
result);
|
||||
p80211pb_free(pb);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Copy the payload data to the buffer */
|
||||
if ( rxdesc.data_len > 0 ) {
|
||||
result = hfa384x_copy_from_bap(hw,
|
||||
hw->bap, rxfid, HFA384x_RX_DATA_OFF,
|
||||
pb->p80211_payload, rxdesc.data_len);
|
||||
if ( result ) {
|
||||
WLAN_LOG_DEBUG4(1,
|
||||
"copy_from_bap(0x%04x, %d, %d) failed, result=%d\n",
|
||||
rxfid,
|
||||
HFA384x_RX_DATA_OFF,
|
||||
rxdesc.data_len,
|
||||
result);
|
||||
p80211pb_free(pb);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
/* Set the length */
|
||||
pb->p80211frmlen = WLAN_HDR_A3_LEN + rxdesc.data_len + WLAN_CRC_LEN;
|
||||
/* Call p80211netdev_rx */
|
||||
p80211netdev_rx(wlandev, pb);
|
||||
break;
|
||||
case 7:
|
||||
WLAN_LOG_DEBUG0(1,"Received monitor frame\n");
|
||||
prism2sta_int_rxmonitor( wlandev, rxfid, &rxdesc);
|
||||
/* Copy to wlansnif skb */
|
||||
/* Call p80211 sniff response function */
|
||||
/* free the locally allocated space */
|
||||
WLAN_HEX_DUMP(1, "monrxdesc", &rxdesc, sizeof(rxdesc));
|
||||
WLAN_HEX_DUMP(1, "monrxfrm", pb->p80211_hdr, pb->p80211frmlen);
|
||||
p80211pb_free(pb);
|
||||
break;
|
||||
default:
|
||||
WLAN_LOG_WARNING1("Received frame on unsupported port=%d\n",
|
||||
HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) );
|
||||
|
||||
p80211pb_free(pb);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1240,6 +1239,160 @@ failed:
|
|||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* prism2sta_int_rxmonitor
|
||||
*
|
||||
* Helper function for int_rx. Handles monitor frames.
|
||||
* Note that this function allocates space for the FCS and sets it
|
||||
* to 0xffffffff. The hfa384x doesn't give us the FCS value but the
|
||||
* higher layers expect it. 0xffffffff is used as a flag to indicate
|
||||
* the FCS is bogus.
|
||||
*
|
||||
* Arguments:
|
||||
* wlandev wlan device structure
|
||||
* rxfid received FID
|
||||
* rxdesc rx descriptor read from card in int_rx
|
||||
*
|
||||
* Returns:
|
||||
* nothing
|
||||
*
|
||||
* Side effects:
|
||||
* Allocates an skb and passes it up via p80211ind_sniff()
|
||||
* Call context:
|
||||
* interrupt
|
||||
----------------------------------------------------------------*/
|
||||
void prism2sta_int_rxmonitor( wlandevice_t *wlandev, UINT16 rxfid, hfa384x_rx_frame_t *rxdesc)
|
||||
{
|
||||
prism2sta_priv_t *priv = wlandev->priv;
|
||||
hfa384x_t *hw = priv->hw;
|
||||
UINT hdrlen = 0;
|
||||
UINT datalen = 0;
|
||||
UINT skblen = 0;
|
||||
p80211msg_lnxind_wlansniffrm_t *msg;
|
||||
UINT8 *datap;
|
||||
UINT16 fc;
|
||||
struct sk_buff *skb;
|
||||
|
||||
DBFENTER;
|
||||
/* Don't forget the status, time, and data_len fields are in host order */
|
||||
/* Figure out how big the frame is */
|
||||
fc = ieee2host16(rxdesc->frame_control);
|
||||
switch ( WLAN_GET_FC_FTYPE(fc) )
|
||||
{
|
||||
case WLAN_FTYPE_DATA:
|
||||
if ( WLAN_GET_FC_TODS(fc) && WLAN_GET_FC_FROMDS(fc) ) {
|
||||
hdrlen = WLAN_HDR_A4_LEN;
|
||||
} else {
|
||||
hdrlen = WLAN_HDR_A3_LEN;
|
||||
}
|
||||
datalen = rxdesc->data_len;
|
||||
break;
|
||||
case WLAN_FTYPE_MGMT:
|
||||
hdrlen = WLAN_HDR_A3_LEN;
|
||||
datalen = rxdesc->data_len;
|
||||
break;
|
||||
case WLAN_FTYPE_CTL:
|
||||
switch ( WLAN_GET_FC_FSTYPE(fc) )
|
||||
{
|
||||
case WLAN_FSTYPE_PSPOLL:
|
||||
case WLAN_FSTYPE_RTS:
|
||||
case WLAN_FSTYPE_CFEND:
|
||||
case WLAN_FSTYPE_CFENDCFACK:
|
||||
hdrlen = 16;
|
||||
break;
|
||||
case WLAN_FSTYPE_CTS:
|
||||
case WLAN_FSTYPE_ACK:
|
||||
hdrlen = 10;
|
||||
break;
|
||||
}
|
||||
datalen = 0;
|
||||
break;
|
||||
}
|
||||
/* Allocate an ind message+framesize skb */
|
||||
skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) +
|
||||
hdrlen + datalen + WLAN_CRC_LEN;
|
||||
skb = alloc_skb(skblen, GFP_ATOMIC);
|
||||
skb_put(skb, skblen);
|
||||
datap = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t);
|
||||
msg = (p80211msg_lnxind_wlansniffrm_t*)skb->data;
|
||||
|
||||
/* Initialize the message members */
|
||||
msg->msgcode = DIDmsg_lnxind_wlansniffrm;
|
||||
msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
|
||||
strcpy(msg->devname, wlandev->name);
|
||||
|
||||
msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
|
||||
msg->hosttime.status = 0;
|
||||
msg->hosttime.len = 4;
|
||||
msg->hosttime.data = jiffies;
|
||||
|
||||
msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
|
||||
msg->mactime.status = 0;
|
||||
msg->mactime.len = 4;
|
||||
msg->mactime.data = rxdesc->time;
|
||||
|
||||
msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
|
||||
msg->channel.status = P80211ENUM_msgitem_status_no_value;
|
||||
msg->channel.len = 4;
|
||||
msg->channel.data = 0;
|
||||
|
||||
msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
|
||||
msg->rssi.status = P80211ENUM_msgitem_status_no_value;
|
||||
msg->rssi.len = 4;
|
||||
msg->rssi.data = 0;
|
||||
|
||||
msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
|
||||
msg->sq.status = P80211ENUM_msgitem_status_no_value;
|
||||
msg->sq.len = 4;
|
||||
msg->sq.data = 0;
|
||||
|
||||
msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
|
||||
msg->signal.status = 0;
|
||||
msg->signal.len = 4;
|
||||
msg->signal.data = rxdesc->signal;
|
||||
|
||||
msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
|
||||
msg->noise.status = 0;
|
||||
msg->noise.len = 4;
|
||||
msg->noise.data = rxdesc->silence;
|
||||
|
||||
msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
|
||||
msg->rate.status = 0;
|
||||
msg->rate.len = 4;
|
||||
msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
|
||||
|
||||
msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
|
||||
msg->istx.status = 0;
|
||||
msg->istx.len = 4;
|
||||
msg->istx.data = P80211ENUM_truth_false;
|
||||
|
||||
msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
|
||||
msg->frmlen.status = 0;
|
||||
msg->frmlen.len = 4;
|
||||
msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN;
|
||||
|
||||
/* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
|
||||
memcpy( datap, &(rxdesc->frame_control), hdrlen);
|
||||
|
||||
/* If any, copy the data from the card to the skb */
|
||||
if ( datalen > 0 )
|
||||
{
|
||||
hfa384x_copy_from_bap(hw,
|
||||
hw->bap, rxfid, HFA384x_RX_DATA_OFF,
|
||||
datap + hdrlen, datalen);
|
||||
}
|
||||
|
||||
/* Set the CRC */
|
||||
memset( datap + skb->len - WLAN_CRC_LEN, 0xff, WLAN_CRC_LEN);
|
||||
|
||||
/* Pass it up */
|
||||
p80211ind_sniff(wlandev, skb);
|
||||
|
||||
DBFEXIT;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* prism2sta_int_alloc
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue