diff options
author | Luis Carlos Cobo <luisca@cozybit.com> | 2007-08-02 13:16:55 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:50:13 -0400 |
commit | 965f8bbc6c92233600b176f4c80299f6766df9bd (patch) | |
tree | 85043fb97112a148d69171b744568fa78de2e05d /drivers/net/wireless/libertas/rx.c | |
parent | 9483f03150cbfa1f706355b7f9d218d6086c6fce (diff) |
[PATCH] libertas: monitor mode support for OLPC firmware
Driver support for the monitor mode support that will be available in the next
OLPC 'bleeding edge' Marvell firmware release (most likely, 5.110.16.p2).
To activate monitor mode,
echo mode > /sys/class/net/{ethX,mshX}/device/libertas_rtap
where mode is the hex mask that specifies which frames to sniff (in short, 0x1
for data, 0x2 for all management but beacons, 0x4 for beacons). Any non zero
mode will activate the monitor mode, inhibiting transmission in ethX and mshX
interfaces and routing all the incoming traffic to a new rtapX interface that
will output the packets in 802.11+radiotap headers format.
Signed-off-by: Luis Carlos Cobo <luisca@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/rx.c')
-rw-r--r-- | drivers/net/wireless/libertas/rx.c | 49 |
1 files changed, 21 insertions, 28 deletions
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 83a7765fd23c..09def943b910 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c | |||
@@ -138,12 +138,15 @@ void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb) | |||
138 | { | 138 | { |
139 | lbs_deb_rx("skb->data %p\n", skb->data); | 139 | lbs_deb_rx("skb->data %p\n", skb->data); |
140 | 140 | ||
141 | if (priv->mesh_dev && IS_MESH_FRAME(skb)) | 141 | if (priv->adapter->monitormode != WLAN_MONITOR_OFF) { |
142 | skb->protocol = eth_type_trans(skb, priv->mesh_dev); | 142 | skb->protocol = eth_type_trans(skb, priv->rtap_net_dev); |
143 | else | 143 | } else { |
144 | skb->protocol = eth_type_trans(skb, priv->dev); | 144 | if (priv->mesh_dev && IS_MESH_FRAME(skb)) |
145 | skb->protocol = eth_type_trans(skb, priv->mesh_dev); | ||
146 | else | ||
147 | skb->protocol = eth_type_trans(skb, priv->dev); | ||
148 | } | ||
145 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 149 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
146 | |||
147 | netif_rx(skb); | 150 | netif_rx(skb); |
148 | } | 151 | } |
149 | 152 | ||
@@ -170,7 +173,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) | |||
170 | 173 | ||
171 | lbs_deb_enter(LBS_DEB_RX); | 174 | lbs_deb_enter(LBS_DEB_RX); |
172 | 175 | ||
173 | if (priv->adapter->linkmode == WLAN_LINKMODE_802_11) | 176 | if (priv->adapter->monitormode != WLAN_MONITOR_OFF) |
174 | return process_rxed_802_11_packet(priv, skb); | 177 | return process_rxed_802_11_packet(priv, skb); |
175 | 178 | ||
176 | p_rx_pkt = (struct rxpackethdr *) skb->data; | 179 | p_rx_pkt = (struct rxpackethdr *) skb->data; |
@@ -290,21 +293,22 @@ static u8 convert_mv_rate_to_radiotap(u8 rate) | |||
290 | return 11; | 293 | return 11; |
291 | case 3: /* 11 Mbps */ | 294 | case 3: /* 11 Mbps */ |
292 | return 22; | 295 | return 22; |
293 | case 4: /* 6 Mbps */ | 296 | /* case 4: reserved */ |
297 | case 5: /* 6 Mbps */ | ||
294 | return 12; | 298 | return 12; |
295 | case 5: /* 9 Mbps */ | 299 | case 6: /* 9 Mbps */ |
296 | return 18; | 300 | return 18; |
297 | case 6: /* 12 Mbps */ | 301 | case 7: /* 12 Mbps */ |
298 | return 24; | 302 | return 24; |
299 | case 7: /* 18 Mbps */ | 303 | case 8: /* 18 Mbps */ |
300 | return 36; | 304 | return 36; |
301 | case 8: /* 24 Mbps */ | 305 | case 9: /* 24 Mbps */ |
302 | return 48; | 306 | return 48; |
303 | case 9: /* 36 Mbps */ | 307 | case 10: /* 36 Mbps */ |
304 | return 72; | 308 | return 72; |
305 | case 10: /* 48 Mbps */ | 309 | case 11: /* 48 Mbps */ |
306 | return 96; | 310 | return 96; |
307 | case 11: /* 54 Mbps */ | 311 | case 12: /* 54 Mbps */ |
308 | return 108; | 312 | return 108; |
309 | } | 313 | } |
310 | lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate); | 314 | lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate); |
@@ -355,14 +359,13 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) | |||
355 | skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); | 359 | skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); |
356 | 360 | ||
357 | /* create the exported radio header */ | 361 | /* create the exported radio header */ |
358 | switch (priv->adapter->radiomode) { | 362 | if(priv->adapter->monitormode == WLAN_MONITOR_OFF) { |
359 | case WLAN_RADIOMODE_NONE: | ||
360 | /* no radio header */ | 363 | /* no radio header */ |
361 | /* chop the rxpd */ | 364 | /* chop the rxpd */ |
362 | skb_pull(skb, sizeof(struct rxpd)); | 365 | skb_pull(skb, sizeof(struct rxpd)); |
363 | break; | 366 | } |
364 | 367 | ||
365 | case WLAN_RADIOMODE_RADIOTAP: | 368 | else { |
366 | /* radiotap header */ | 369 | /* radiotap header */ |
367 | radiotap_hdr.hdr.it_version = 0; | 370 | radiotap_hdr.hdr.it_version = 0; |
368 | /* XXX must check this value for pad */ | 371 | /* XXX must check this value for pad */ |
@@ -400,16 +403,6 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) | |||
400 | rx_radiotap_hdr)); | 403 | rx_radiotap_hdr)); |
401 | memcpy(pradiotap_hdr, &radiotap_hdr, | 404 | memcpy(pradiotap_hdr, &radiotap_hdr, |
402 | sizeof(struct rx_radiotap_hdr)); | 405 | sizeof(struct rx_radiotap_hdr)); |
403 | break; | ||
404 | |||
405 | default: | ||
406 | /* unknown header */ | ||
407 | lbs_pr_alert("Unknown radiomode %i\n", | ||
408 | priv->adapter->radiomode); | ||
409 | /* don't export any header */ | ||
410 | /* chop the rxpd */ | ||
411 | skb_pull(skb, sizeof(struct rxpd)); | ||
412 | break; | ||
413 | } | 406 | } |
414 | 407 | ||
415 | /* Take the data rate from the rxpd structure | 408 | /* Take the data rate from the rxpd structure |