Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 21315
b: refs/heads/master
c: 15745a7
h: refs/heads/master
i:
  21313: 88e7d3c
  21311: d919ec8
v: v3
  • Loading branch information
Stefan Rompf authored and John W. Linville committed Mar 17, 2006
1 parent 981482f commit 86d01cf
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 171e7b2f1f50f112d3ce8a829a3e79c5739b3132
refs/heads/master: 15745a7dd1ac6bf1ef7959040f864c78a95aa35b
95 changes: 84 additions & 11 deletions trunk/drivers/net/wireless/ipw2100.c
Original file line number Diff line number Diff line change
Expand Up @@ -2390,15 +2390,6 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
}
#ifdef CONFIG_IPW2100_MONITOR
if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
priv->config & CFG_CRC_CHECK &&
status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
priv->ieee->stats.rx_errors++;
return;
}
#endif

if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
!(priv->status & STATUS_ASSOCIATED))) {
Expand Down Expand Up @@ -2446,6 +2437,88 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
priv->rx_queue.drv[i].host_addr = packet->dma_addr;
}

#ifdef CONFIG_IPW2100_MONITOR

static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
struct ieee80211_rx_stats *stats)
{
struct ipw2100_status *status = &priv->status_queue.drv[i];
struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];

IPW_DEBUG_RX("Handler...\n");

/* Magic struct that slots into the radiotap header -- no reason
* to build this manually element by element, we can write it much
* more efficiently than we can parse it. ORDER MATTERS HERE */
struct ipw_rt_hdr {
struct ieee80211_radiotap_header rt_hdr;
s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
} *ipw_rt;

if (unlikely(status->frame_size > skb_tailroom(packet->skb) - sizeof(struct ipw_rt_hdr))) {
IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
" Dropping.\n",
priv->net_dev->name,
status->frame_size, skb_tailroom(packet->skb));
priv->ieee->stats.rx_errors++;
return;
}

if (unlikely(!netif_running(priv->net_dev))) {
priv->ieee->stats.rx_errors++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
}

if (unlikely(priv->config & CFG_CRC_CHECK &&
status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
priv->ieee->stats.rx_errors++;
return;
}

pci_unmap_single(priv->pci_dev,
packet->dma_addr,
sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
memmove(packet->skb->data + sizeof(struct ipw_rt_hdr),
packet->skb->data, status->frame_size);

ipw_rt = (struct ipw_rt_hdr *) packet->skb->data;

ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total header+data */

ipw_rt->rt_hdr.it_present = 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL;

ipw_rt->rt_dbmsignal = status->rssi + IPW2100_RSSI_TO_DBM;

skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr));

if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
priv->ieee->stats.rx_errors++;

/* ieee80211_rx failed, so it didn't free the SKB */
dev_kfree_skb_any(packet->skb);
packet->skb = NULL;
}

/* We need to allocate a new SKB and attach it to the RDB. */
if (unlikely(ipw2100_alloc_skb(priv, packet))) {
IPW_DEBUG_WARNING(
"%s: Unable to allocate SKB onto RBD ring - disabling "
"adapter.\n", priv->net_dev->name);
/* TODO: schedule adapter shutdown */
IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
}

/* Update the RDB entry */
priv->rx_queue.drv[i].host_addr = packet->dma_addr;
}

#endif

static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
{
struct ipw2100_status *status = &priv->status_queue.drv[i];
Expand Down Expand Up @@ -2577,7 +2650,7 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
case P8023_DATA_VAL:
#ifdef CONFIG_IPW2100_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
isr_rx(priv, i, &stats);
isr_rx_monitor(priv, i, &stats);
break;
}
#endif
Expand Down Expand Up @@ -3882,7 +3955,7 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
#ifdef CONFIG_IPW2100_MONITOR
case IW_MODE_MONITOR:
priv->last_mode = priv->ieee->iw_mode;
priv->net_dev->type = ARPHRD_IEEE80211;
priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
break;
#endif /* CONFIG_IPW2100_MONITOR */
}
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/net/wireless/ipw2100.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@

#include <net/ieee80211.h>

#ifdef CONFIG_IPW2100_MONITOR
#include <net/ieee80211_radiotap.h>
#endif

#include <linux/workqueue.h>

struct ipw2100_priv;
Expand Down

0 comments on commit 86d01cf

Please sign in to comment.