diff options
Diffstat (limited to 'sys-kernel/thinkpad-sources/files/2.6.28/02-ipw2200-inject-for-2.6.27.patch')
-rw-r--r-- | sys-kernel/thinkpad-sources/files/2.6.28/02-ipw2200-inject-for-2.6.27.patch | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/sys-kernel/thinkpad-sources/files/2.6.28/02-ipw2200-inject-for-2.6.27.patch b/sys-kernel/thinkpad-sources/files/2.6.28/02-ipw2200-inject-for-2.6.27.patch new file mode 100644 index 0000000..ec44f16 --- /dev/null +++ b/sys-kernel/thinkpad-sources/files/2.6.28/02-ipw2200-inject-for-2.6.27.patch @@ -0,0 +1,86 @@ +--- a/drivers/net/wireless/ipw2200.c 2007-10-07 12:41:29.000000000 +0200 ++++ b/drivers/net/wireless/ipw2200.c 2007-10-07 12:50:43.000000000 +0200 +@@ -31,7 +31,7 @@ + ******************************************************************************/ + + #include "ipw2200.h" +- ++#include <linux/version.h> + + #ifndef KBUILD_EXTMOD + #define VK "k" +@@ -1862,6 +1862,66 @@ + static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO, + show_net_stats, store_net_stats); + ++static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, int pri); ++ ++/* SYSFS INJECT */ ++static ssize_t store_inject(struct device *d, ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) ++ struct device_attribute *attr, ++#endif ++ const char *buf, size_t count) ++{ ++ struct ipw_priv *priv = (struct ipw_priv *)d->driver_data; ++ struct ieee80211_device *ieee = priv->ieee; ++ struct ieee80211_txb * txb; ++ struct sk_buff *skb_frag; ++ unsigned char * newbuf; ++ unsigned long flags; ++ ++ // should test (ieee->is_queue_full) ++ ++ // Fw only accepts data, so avoid accidental fw errors. ++ if ( (buf[0]&0x0c) != '\x08') { ++ //printk("ipw2200: inject: discarding non-data frame (type=%02X)\n",(int)(unsigned char)buf[0]); ++ return count; ++ } ++ ++ if (count>1500) { ++ count=1500; ++ printk("ipw2200: inject: cutting down frame to 1500 bytes\n"); ++ } ++ ++ spin_lock_irqsave(&priv->lock, flags); ++ ++ // Create a txb with one skb ++ txb = kmalloc(sizeof(struct ieee80211_txb) + sizeof(u8 *), GFP_ATOMIC); ++ if (!txb) ++ goto nosepuede; ++ txb->nr_frags=1; ++ txb->frag_size = ieee->tx_headroom; ++ txb->fragments[0]=__dev_alloc_skb(count + ieee->tx_headroom, GFP_ATOMIC); ++ if (!txb->fragments[0]) { ++ kfree(txb); ++ goto nosepuede; ++ } ++ skb_reserve(txb->fragments[0], ieee->tx_headroom); ++ txb->encrypted=0; ++ txb->payload_size=count; ++ skb_frag = txb->fragments[0]; ++ newbuf=skb_put(skb_frag, count); ++ ++ // copy data into txb->skb and send it ++ memcpy(newbuf, buf, count); ++ ++ ipw_tx_skb(priv, txb, 0); ++ ++nosepuede: ++ spin_unlock_irqrestore(&priv->lock, flags); ++ return count; ++} ++ ++static DEVICE_ATTR(inject, S_IWUSR, NULL, store_inject); ++ + static ssize_t show_channels(struct device *d, + struct device_attribute *attr, + char *buf) +@@ -11478,6 +11538,7 @@ + #ifdef CONFIG_IPW2200_PROMISCUOUS + &dev_attr_rtap_iface.attr, + &dev_attr_rtap_filter.attr, ++ &dev_attr_inject.attr, + #endif + NULL + }; |