* Re: Sis900 and VLAN 8021q.o incompatible/MTU troubles
From: Francois Romieu @ 2005-05-12 20:37 UTC (permalink / raw)
To: Axel Reinhold; +Cc: netdev
In-Reply-To: <200505120743.j4C7hWKI011583@l0p.le-gobw.de>
Axel Reinhold <Axel.Reinhold@le-gobw.de> :
[...]
> my sis900 is running fine in standard mode. Together with 8021q.o
> i get all kinds of troubles - for example samba is no more working at
> all - without vlan everything is fine - with vlans everything basically
> works - but only to a certain point, then it screws up.
It can help if you provide:
- the kernel revision;
- some vlan context (commands issued ? vlan only or mixed config ?);
- the range of working size for simple ping.
--
Ueimor
^ permalink raw reply
* Re: issue with new TCP TSO stuff
From: Herbert Xu @ 2005-05-12 21:47 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050512.131349.32715242.davem@davemloft.net>
On Thu, May 12, 2005 at 01:13:49PM -0700, David S. Miller wrote:
>
> But this still has the early free problem, I think. If an ACK
> comes in which releases an SKB on the chain, while the driver
> is still working with that chain, we cannot free the SKB. We
> have to do it some time later.
This is fine because we have to skb_clone the packet. Otherwise
the next pointer for the frag/xmit list will be messed up.
> One way to prevent that would be to do an skb_get() on every
> SKB in the chain, but then we're back to the original problem
> of all the extra atomic operations.
You're being frugal Dave :) I was happy with one skb_clone per
skb and you're having problems with skb_get? :)
Seriously, we already do one skb_clone for every packet sent
so we won't be incurring any extra overhead with this.
> A secondary point is that I'd like to use a name other than
> NETIF_F_FRAGLIST because people are super confused as to what this
> device flag even means. Some people confuse it with NETIF_F_SG,
> others thing it takes a huge UDP frame and fragments it into MTU sized
> IP frames and checksums the whole thing. None of which are true.
Fine by me. But you know I'm not good with names :)
> Loopback is the only driver which supports this properly, by
> simply doing nothing with the packet :-)
If we implement these in the TSO-capable drivers, IPsec could benefit
as well. Two inbound IPsec fragments that are reassembled are currently
linearised in dev_queue_xmit. With this it can be sent directly to
the driver.
> So back to the main point, we are in quite a conundrum. The whole
> point of TSO is to offload the segmentation overhead, but we're in
> fact making the TCP output engine more expensive for the TSO path.
I'll need to finish reading the entire patch before I can respond to
this.
Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: issue with new TCP TSO stuff
From: Herbert Xu @ 2005-05-12 22:10 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050512214744.GA21958@gondor.apana.org.au>
On Fri, May 13, 2005 at 07:47:44AM +1000, herbert wrote:
>
> You're being frugal Dave :) I was happy with one skb_clone per
> skb and you're having problems with skb_get? :)
>
> Seriously, we already do one skb_clone for every packet sent
> so we won't be incurring any extra overhead with this.
Nevermind, you're comparing to the existing TSO implementation.
So how big exactly is the slowdown?
> > A secondary point is that I'd like to use a name other than
> > NETIF_F_FRAGLIST because people are super confused as to what this
> > device flag even means. Some people confuse it with NETIF_F_SG,
> > others thing it takes a huge UDP frame and fragments it into MTU sized
> > IP frames and checksums the whole thing. None of which are true.
>
> Fine by me. But you know I'm not good with names :)
This just occured to me, what about NETIF_F_SKBLIST?
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: issue with new TCP TSO stuff
From: David S. Miller @ 2005-05-12 22:34 UTC (permalink / raw)
To: ak; +Cc: netdev
In-Reply-To: <20050512202629.GB72662@muc.de>
From: Andi Kleen <ak@muc.de>
Subject: Re: issue with new TCP TSO stuff
Date: 12 May 2005 22:26:29 +0200,Thu, 12 May 2005 22:26:29 +0200
> On Thu, May 12, 2005 at 01:03:41PM -0700, David S. Miller wrote:
> > I used my brain to analyze this slowdown, instead of the
> > computer, I'm sorry if that disturbs you :-)
>
> What disturbs me is your conclusion :)
Fair enough, I'll get some numbers. :-)
^ permalink raw reply
* Re: issue with new TCP TSO stuff
From: David S. Miller @ 2005-05-12 22:46 UTC (permalink / raw)
To: herbert; +Cc: netdev
In-Reply-To: <20050512214744.GA21958@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Subject: Re: issue with new TCP TSO stuff
Date: Fri, 13 May 2005 07:47:44 +1000
> On Thu, May 12, 2005 at 01:13:49PM -0700, David S. Miller wrote:
> > One way to prevent that would be to do an skb_get() on every
> > SKB in the chain, but then we're back to the original problem
> > of all the extra atomic operations.
>
> You're being frugal Dave :) I was happy with one skb_clone per
> skb and you're having problems with skb_get? :)
>
> Seriously, we already do one skb_clone for every packet sent
> so we won't be incurring any extra overhead with this.
It's "relative to existing TSO" that this cost is. For the existing
TSO handling we do one atomic ref for the entire TSO frame. Now we're
going to do it for the N frames that a TSO packet is composed of.
So what this ends up meaning is that the new TSO code's only gain
(relative to non-TSO) will basically be that we:
1) Incur only one trip down the device XMIT path for N frames.
2) Only send one set of headers of the bus to the device.
Whereas the existing TSO support has a third benefit which is:
3) TSO frames are segmented as singular SKBs
This reduction in SKB allocations and subsequent handling is
non-trivial.
It has ramifications beyond the transmit path. When the ACKs
come back in, we do less kfree_skb() calls, for example. But
then again, we had all of that ugly TSO partial-ACK trimming
stuff.
I'm going to do some profiling to make sure it really matters.
^ permalink raw reply
* ipw2100: intrusive cleanups, working this time ;-)
From: Pavel Machek @ 2005-05-12 22:50 UTC (permalink / raw)
To: jketreno, netdev, kernel list; +Cc: jbohac, jbenc
Hi!
There's a lot to clean up in header file, too... And this time it
actually works.
Now, I'd like to clean it a bit more and then submit it to akpm for
-mm series. Will someone hate me for doing that?
Pavel
--- clean-mm/drivers/net/wireless/ipw2100.c 2005-05-11 22:00:02.000000000 +0200
+++ linux-mm/drivers/net/wireless/ipw2100.c 2005-05-13 00:42:27.000000000 +0200
@@ -106,7 +106,7 @@
tx_pend_list : Holds used Tx buffers waiting to go into the TBD ring
TAIL modified ipw2100_tx()
- HEAD modified by X__ipw2100_tx_send_data()
+ HEAD modified by ipw2100_tx_send_data()
msg_free_list : Holds pre-allocated Msg (Command) buffers
TAIL modified in __ipw2100_tx_process()
@@ -114,7 +114,7 @@
msg_pend_list : Holds used Msg buffers waiting to go into the TBD ring
TAIL modified in ipw2100_hw_send_command()
- HEAD modified in X__ipw2100_tx_send_commands()
+ HEAD modified in ipw2100_tx_send_commands()
The flow of data on the TX side is as follows:
@@ -150,7 +150,6 @@
#include <linux/skbuff.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#define __KERNEL_SYSCALLS__
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
@@ -174,11 +173,6 @@
#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
-/* Debugging stuff */
-#ifdef CONFIG_IPW_DEBUG
-#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
-#endif
-
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT);
@@ -189,9 +183,7 @@
static int channel = 0;
static int associate = 1;
static int disable = 0;
-#ifdef CONFIG_PM
static struct ipw2100_fw ipw2100_firmware;
-#endif
#include <linux/moduleparam.h>
module_param(debug, int, 0444);
@@ -286,8 +278,8 @@
/* Pre-decl until we get the code solid and then we can clean it up */
-static void X__ipw2100_tx_send_commands(struct ipw2100_priv *priv);
-static void X__ipw2100_tx_send_data(struct ipw2100_priv *priv);
+static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
+static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
static int ipw2100_adapter_setup(struct ipw2100_priv *priv);
static void ipw2100_queues_initialize(struct ipw2100_priv *priv);
@@ -735,8 +727,8 @@
list_add_tail(element, &priv->msg_pend_list);
INC_STAT(&priv->msg_pend_stat);
- X__ipw2100_tx_send_commands(priv);
- X__ipw2100_tx_send_data(priv);
+ ipw2100_tx_send_commands(priv);
+ ipw2100_tx_send_data(priv);
spin_unlock_irqrestore(&priv->low_lock, flags);
@@ -915,12 +907,10 @@
if (i == 10000)
return -EIO; /* TODO: better error value */
-//#if CONFIG_IPW2100_D0ENABLED
/* set D0 standby bit */
read_register(priv->net_dev, IPW_REG_GP_CNTRL, &r);
write_register(priv->net_dev, IPW_REG_GP_CNTRL,
r | IPW_AUX_HOST_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
-//#endif
return 0;
}
@@ -941,11 +931,6 @@
u32 address;
int err;
-#ifndef CONFIG_PM
- /* Fetch the firmware and microcode */
- struct ipw2100_fw ipw2100_firmware;
-#endif
-
if (priv->fatal_error) {
IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
"fatal error %d. Interface must be brought down.\n",
@@ -953,7 +938,6 @@
return -EINVAL;
}
-#ifdef CONFIG_PM
if (!ipw2100_firmware.version) {
err = ipw2100_get_firmware(priv, &ipw2100_firmware);
if (err) {
@@ -963,15 +947,6 @@
goto fail;
}
}
-#else
- err = ipw2100_get_firmware(priv, &ipw2100_firmware);
- if (err) {
- IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
- priv->net_dev->name, err);
- priv->fatal_error = IPW2100_ERR_FW_LOAD;
- goto fail;
- }
-#endif
priv->firmware_version = ipw2100_firmware.version;
/* s/w reset and clock stabilization */
@@ -1026,18 +1001,6 @@
goto fail;
}
-#ifndef CONFIG_PM
- /*
- * When the .resume method of the driver is called, the other
- * part of the system, i.e. the ide driver could still stay in
- * the suspend stage. This prevents us from loading the firmware
- * from the disk. --YZ
- */
-
- /* free any storage allocated for firmware image */
- ipw2100_release_firmware(priv, &ipw2100_firmware);
-#endif
-
/* zero out Domain 1 area indirectly (Si requirement) */
for (address = IPW_HOST_FW_SHARED_AREA0;
address < IPW_HOST_FW_SHARED_AREA0_END; address += 4)
@@ -1083,8 +1046,6 @@
{
struct ipw2100_ordinals *ord = &priv->ordinals;
- IPW_DEBUG_INFO("enter\n");
-
read_register(priv->net_dev, IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1,
&ord->table1_addr);
@@ -1095,10 +1056,6 @@
read_nic_dword(priv->net_dev, ord->table2_addr, &ord->table2_size);
ord->table2_size &= 0x0000FFFF;
-
- IPW_DEBUG_INFO("table 1 size: %d\n", ord->table1_size);
- IPW_DEBUG_INFO("table 2 size: %d\n", ord->table2_size);
- IPW_DEBUG_INFO("exit\n");
}
static inline void ipw2100_hw_set_gpio(struct ipw2100_priv *priv)
@@ -1117,7 +1074,6 @@
{
#define MAX_RF_KILL_CHECKS 5
#define RF_KILL_CHECK_DELAY 40
-#define RF_KILL_CHECK_THRESHOLD 3
unsigned short value = 0;
u32 reg = 0;
@@ -1198,8 +1154,6 @@
int i;
u32 inta, inta_mask, gpio;
- IPW_DEBUG_INFO("enter\n");
-
if (priv->status & STATUS_RUNNING)
return 0;
@@ -1286,9 +1240,6 @@
/* The adapter has been reset; we are not associated */
priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
@@ -1598,8 +1549,6 @@
};
int err;
- IPW_DEBUG_INFO("enter\n");
-
IPW_DEBUG_SCAN("setting scan options\n");
cmd.host_command_parameters[0] = 0;
@@ -1643,8 +1592,6 @@
return 0;
}
- IPW_DEBUG_INFO("enter\n");
-
/* Not clearing here; doing so makes iwlist always return nothing...
*
* We should modify the table logic to use aging tables vs. clearing
@@ -1657,8 +1604,6 @@
if (err)
priv->status &= ~STATUS_SCANNING;
- IPW_DEBUG_INFO("exit\n");
-
return err;
}
@@ -2285,18 +2230,10 @@
* The size of the constructed ethernet
*
*/
-#ifdef CONFIG_IPW2100_RX_DEBUG
-u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
-#endif
static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
int i)
{
-#ifdef CONFIG_IPW_DEBUG_C3
- struct ipw2100_status *status = &priv->status_queue.drv[i];
- u32 match, reg;
- int j;
-#endif
#ifdef ACPI_CSTATE_LIMIT_DEFINED
int limit;
#endif
@@ -2314,35 +2251,6 @@
}
#endif
-#ifdef CONFIG_IPW_DEBUG_C3
- /* Halt the fimrware so we can get a good image */
- write_register(priv->net_dev, IPW_REG_RESET_REG,
- IPW_AUX_HOST_RESET_REG_STOP_MASTER);
- j = 5;
- do {
- udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY);
- read_register(priv->net_dev, IPW_REG_RESET_REG, ®);
-
- if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
- break;
- } while (j--);
-
- match = ipw2100_match_buf(priv, (u8*)status,
- sizeof(struct ipw2100_status),
- SEARCH_SNAPSHOT);
- if (match < SEARCH_SUCCESS)
- IPW_DEBUG_INFO("%s: DMA status match in Firmware at "
- "offset 0x%06X, length %d:\n",
- priv->net_dev->name, match,
- sizeof(struct ipw2100_status));
- else
- IPW_DEBUG_INFO("%s: No DMA status match in "
- "Firmware.\n", priv->net_dev->name);
-
- printk_buf((u8*)priv->status_queue.drv,
- sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
-#endif
-
priv->fatal_error = IPW2100_ERR_C3_CORRUPTION;
priv->ieee->stats.rx_errors++;
schedule_reset(priv);
@@ -2394,19 +2302,7 @@
skb_put(packet->skb, status->frame_size);
-#ifdef CONFIG_IPW2100_RX_DEBUG
- /* Make a copy of the frame so we can dump it to the logs if
- * ieee80211_rx fails */
- memcpy(packet_data, packet->skb->data,
- min(status->frame_size, IPW_RX_NIC_BUFFER_LENGTH));
-#endif
-
if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
-#ifdef CONFIG_IPW2100_RX_DEBUG
- IPW_DEBUG_DROP("%s: Non consumed packet:\n",
- priv->net_dev->name);
- printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
-#endif
priv->ieee->stats.rx_errors++;
/* ieee80211_rx failed, so it didn't free the SKB */
@@ -2847,7 +2743,7 @@
}
-static void X__ipw2100_tx_send_commands(struct ipw2100_priv *priv)
+static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
{
struct list_head *element;
struct ipw2100_tx_packet *packet;
@@ -2915,10 +2811,10 @@
/*
- * X__ipw2100_tx_send_data
+ * ipw2100_tx_send_data
*
*/
-static void X__ipw2100_tx_send_data(struct ipw2100_priv *priv)
+static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
{
struct list_head *element;
struct ipw2100_tx_packet *packet;
@@ -3133,8 +3029,8 @@
IPW2100_INTA_TX_TRANSFER);
__ipw2100_tx_complete(priv);
- X__ipw2100_tx_send_commands(priv);
- X__ipw2100_tx_send_data(priv);
+ ipw2100_tx_send_commands(priv);
+ ipw2100_tx_send_data(priv);
}
if (inta & IPW2100_INTA_TX_COMPLETE) {
@@ -3192,8 +3088,6 @@
ipw2100_enable_interrupts(priv);
spin_unlock_irqrestore(&priv->low_lock, flags);
-
- IPW_DEBUG_ISR("exit\n");
}
@@ -3285,7 +3179,7 @@
list_add_tail(element, &priv->tx_pend_list);
INC_STAT(&priv->tx_pend_stat);
- X__ipw2100_tx_send_data(priv);
+ ipw2100_tx_send_data(priv);
spin_unlock_irqrestore(&priv->low_lock, flags);
return 0;
@@ -3662,96 +3556,6 @@
}
static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
-
-static ssize_t show_memory(struct device *d, char *buf)
-{
- struct ipw2100_priv *priv = dev_get_drvdata(d);
- struct net_device *dev = priv->net_dev;
- static unsigned long loop = 0;
- int len = 0;
- u32 buffer[4];
- int i;
- char line[81];
-
- if (loop >= 0x30000)
- loop = 0;
-
- /* sysfs provides us PAGE_SIZE buffer */
- while (len < PAGE_SIZE - 128 && loop < 0x30000) {
-
- if (priv->snapshot[0]) for (i = 0; i < 4; i++)
- buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
- else for (i = 0; i < 4; i++)
- read_nic_dword(dev, loop + i * 4, &buffer[i]);
-
- if (priv->dump_raw)
- len += sprintf(buf + len,
- "%c%c%c%c"
- "%c%c%c%c"
- "%c%c%c%c"
- "%c%c%c%c",
- ((u8*)buffer)[0x0],
- ((u8*)buffer)[0x1],
- ((u8*)buffer)[0x2],
- ((u8*)buffer)[0x3],
- ((u8*)buffer)[0x4],
- ((u8*)buffer)[0x5],
- ((u8*)buffer)[0x6],
- ((u8*)buffer)[0x7],
- ((u8*)buffer)[0x8],
- ((u8*)buffer)[0x9],
- ((u8*)buffer)[0xa],
- ((u8*)buffer)[0xb],
- ((u8*)buffer)[0xc],
- ((u8*)buffer)[0xd],
- ((u8*)buffer)[0xe],
- ((u8*)buffer)[0xf]);
- else
- len += sprintf(buf + len, "%s\n",
- snprint_line(line, sizeof(line),
- (u8*)buffer, 16, loop));
- loop += 16;
- }
-
- return len;
-}
-
-static ssize_t store_memory(struct device *d, const char *buf, size_t count)
-{
- struct ipw2100_priv *priv = dev_get_drvdata(d);
- struct net_device *dev = priv->net_dev;
- const char *p = buf;
-
- if (count < 1)
- return count;
-
- if (p[0] == '1' ||
- (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
- IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
- dev->name);
- priv->dump_raw = 1;
-
- } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
- tolower(p[1]) == 'f')) {
- IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
- dev->name);
- priv->dump_raw = 0;
-
- } else if (tolower(p[0]) == 'r') {
- IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n",
- dev->name);
- ipw2100_snapshot_free(priv);
-
- } else
- IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
- "reset = clear memory snapshot\n",
- dev->name);
-
- return count;
-}
-static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
-
-
static ssize_t show_ordinals(struct device *d, char *buf)
{
struct ipw2100_priv *priv = dev_get_drvdata(d);
@@ -3837,11 +3641,9 @@
priv->ieee->iw_mode = mode;
-#ifdef CONFIG_PM
/* Indicate ipw2100_download_firmware download firmware
* from disk instead of memory. */
ipw2100_firmware.version = 0;
-#endif
printk(KERN_INFO "%s: Reseting on mode change.\n",
priv->net_dev->name);
@@ -4030,8 +3832,6 @@
unsigned long val;
char *p = buffer;
- IPW_DEBUG_INFO("enter\n");
-
strncpy(buffer, buf, len);
buffer[len] = 0;
@@ -4049,8 +3849,6 @@
priv->ieee->scan_age = val;
IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
}
-
- IPW_DEBUG_INFO("exit\n");
return len;
}
static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
@@ -4117,7 +3915,6 @@
&dev_attr_stats.attr,
&dev_attr_internals.attr,
&dev_attr_bssinfo.attr,
- &dev_attr_memory.attr,
&dev_attr_scan_age.attr,
&dev_attr_fatal_error.attr,
&dev_attr_rf_kill.attr,
@@ -4136,8 +3933,6 @@
{
struct ipw2100_status_queue *q = &priv->status_queue;
- IPW_DEBUG_INFO("enter\n");
-
q->size = entries * sizeof(struct ipw2100_status);
q->drv = (struct ipw2100_status *)pci_alloc_consistent(
priv->pci_dev, q->size, &q->nic);
@@ -4148,31 +3943,22 @@
}
memset(q->drv, 0, q->size);
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
static void status_queue_free(struct ipw2100_priv *priv)
{
- IPW_DEBUG_INFO("enter\n");
-
if (priv->status_queue.drv) {
pci_free_consistent(
priv->pci_dev, priv->status_queue.size,
priv->status_queue.drv, priv->status_queue.nic);
priv->status_queue.drv = NULL;
}
-
- IPW_DEBUG_INFO("exit\n");
}
static int bd_queue_allocate(struct ipw2100_priv *priv,
struct ipw2100_bd_queue *q, int entries)
{
- IPW_DEBUG_INFO("enter\n");
-
memset(q, 0, sizeof(struct ipw2100_bd_queue));
q->entries = entries;
@@ -4183,17 +3969,12 @@
return -ENOMEM;
}
memset(q->drv, 0, q->size);
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
static void bd_queue_free(struct ipw2100_priv *priv,
struct ipw2100_bd_queue *q)
{
- IPW_DEBUG_INFO("enter\n");
-
if (!q)
return;
@@ -4202,24 +3983,18 @@
q->size, q->drv, q->nic);
q->drv = NULL;
}
-
- IPW_DEBUG_INFO("exit\n");
}
static void bd_queue_initialize(
struct ipw2100_priv *priv, struct ipw2100_bd_queue * q,
u32 base, u32 size, u32 r, u32 w)
{
- IPW_DEBUG_INFO("enter\n");
-
IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, q->nic);
write_register(priv->net_dev, base, q->nic);
write_register(priv->net_dev, size, q->entries);
write_register(priv->net_dev, r, q->oldest);
write_register(priv->net_dev, w, q->next);
-
- IPW_DEBUG_INFO("exit\n");
}
static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
@@ -4243,8 +4018,6 @@
void *v;
dma_addr_t p;
- IPW_DEBUG_INFO("enter\n");
-
err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
if (err) {
IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
@@ -4299,8 +4072,6 @@
{
int i;
- IPW_DEBUG_INFO("enter\n");
-
/*
* reinitialize packet info lists
*/
@@ -4339,17 +4110,12 @@
IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE,
IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,
IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX);
-
- IPW_DEBUG_INFO("exit\n");
-
}
static void ipw2100_tx_free(struct ipw2100_priv *priv)
{
int i;
- IPW_DEBUG_INFO("enter\n");
-
bd_queue_free(priv, &priv->tx_queue);
if (!priv->tx_buffers)
@@ -4370,8 +4136,6 @@
kfree(priv->tx_buffers);
priv->tx_buffers = NULL;
-
- IPW_DEBUG_INFO("exit\n");
}
@@ -4380,8 +4144,6 @@
{
int i, j, err = -EINVAL;
- IPW_DEBUG_INFO("enter\n");
-
err = bd_queue_allocate(priv, &priv->rx_queue, RX_QUEUE_LENGTH);
if (err) {
IPW_DEBUG_INFO("failed bd_queue_allocate\n");
@@ -4448,8 +4210,6 @@
static void ipw2100_rx_initialize(struct ipw2100_priv *priv)
{
- IPW_DEBUG_INFO("enter\n");
-
priv->rx_queue.oldest = 0;
priv->rx_queue.available = priv->rx_queue.entries - 1;
priv->rx_queue.next = priv->rx_queue.entries - 1;
@@ -4466,16 +4226,12 @@
/* set up the status queue */
write_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_STATUS_BASE,
priv->status_queue.nic);
-
- IPW_DEBUG_INFO("exit\n");
}
static void ipw2100_rx_free(struct ipw2100_priv *priv)
{
int i;
- IPW_DEBUG_INFO("enter\n");
-
bd_queue_free(priv, &priv->rx_queue);
status_queue_free(priv);
@@ -4494,8 +4250,6 @@
kfree(priv->rx_buffers);
priv->rx_buffers = NULL;
-
- IPW_DEBUG_INFO("exit\n");
}
static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
@@ -4536,8 +4290,6 @@
IPW_DEBUG_HC("SET_MAC_ADDRESS\n");
- IPW_DEBUG_INFO("enter\n");
-
if (priv->config & CFG_CUSTOM_MAC) {
memcpy(cmd.host_command_parameters, priv->mac_addr,
ETH_ALEN);
@@ -4547,8 +4299,6 @@
ETH_ALEN);
err = ipw2100_hw_send_command(priv, &cmd);
-
- IPW_DEBUG_INFO("exit\n");
return err;
}
@@ -4805,47 +4555,6 @@
return 0;
}
-#if 0
-int ipw2100_set_fragmentation_threshold(struct ipw2100_priv *priv,
- u32 threshold, int batch_mode)
-{
- struct host_command cmd = {
- .host_command = FRAG_THRESHOLD,
- .host_command_sequence = 0,
- .host_command_length = 4,
- .host_command_parameters[0] = 0,
- };
- int err;
-
- if (!batch_mode) {
- err = ipw2100_disable_adapter(priv);
- if (err)
- return err;
- }
-
- if (threshold == 0)
- threshold = DEFAULT_FRAG_THRESHOLD;
- else {
- threshold = max(threshold, MIN_FRAG_THRESHOLD);
- threshold = min(threshold, MAX_FRAG_THRESHOLD);
- }
-
- cmd.host_command_parameters[0] = threshold;
-
- IPW_DEBUG_HC("FRAG_THRESHOLD: %u\n", threshold);
-
- err = ipw2100_hw_send_command(priv, &cmd);
-
- if (!batch_mode)
- ipw2100_enable_adapter(priv);
-
- if (!err)
- priv->frag_threshold = threshold;
-
- return err;
-}
-#endif
-
int ipw2100_set_short_retry(struct ipw2100_priv *priv, u32 retry)
{
struct host_command cmd = {
@@ -4935,8 +4644,6 @@
int err;
int len;
- IPW_DEBUG_HC("DISASSOCIATION_BSSID\n");
-
len = ETH_ALEN;
/* The Firmware currently ignores the BSSID and just disassociates from
* the currently associated AP -- but in the off chance that a future
@@ -4950,37 +4657,6 @@
}
#endif
-/*
- * Pseudo code for setting up wpa_frame:
- */
-#if 0
-void x(struct ieee80211_assoc_frame *wpa_assoc)
-{
- struct ipw2100_wpa_assoc_frame frame;
- frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
- IPW_WPA_LISTENINTERVAL |
- IPW_WPA_AP_ADDRESS;
- frame->capab_info = wpa_assoc->capab_info;
- frame->lisen_interval = wpa_assoc->listent_interval;
- memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
-
- /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
- * setup here to test it with.
- *
- * Walk the IEs in the wpa_assoc and figure out the total size of all
- * that data. Stick that into frame->var_ie_len. Then memcpy() all of
- * the IEs from wpa_frame into frame.
- */
- frame->var_ie_len = calculate_ie_len(wpa_assoc);
- memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
-
- ipw2100_set_wpa_ie(priv, &frame, 0);
-}
-#endif
-
-
-
-
static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
struct ipw2100_wpa_assoc_frame *, int)
__attribute__ ((unused));
@@ -4996,8 +4672,6 @@
};
int err;
- IPW_DEBUG_HC("SET_WPA_IE\n");
-
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
if (err)
@@ -5123,8 +4797,6 @@
cmd.host_command_parameters[0] = interval;
- IPW_DEBUG_INFO("enter\n");
-
if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
@@ -5140,9 +4812,6 @@
return err;
}
}
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
@@ -5502,8 +5171,6 @@
int batch_mode = 1;
u8 *bssid;
- IPW_DEBUG_INFO("enter\n");
-
err = ipw2100_disable_adapter(priv);
if (err)
return err;
@@ -5512,9 +5179,6 @@
err = ipw2100_set_channel(priv, priv->channel, batch_mode);
if (err)
return err;
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
#endif /* CONFIG_IPW2100_MONITOR */
@@ -5591,9 +5255,6 @@
if (err)
return err;
*/
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
@@ -5656,8 +5317,6 @@
struct list_head *element;
struct ipw2100_tx_packet *packet;
- IPW_DEBUG_INFO("enter\n");
-
spin_lock_irqsave(&priv->low_lock, flags);
if (priv->status & STATUS_ASSOCIATED)
@@ -5679,9 +5338,6 @@
INC_STAT(&priv->tx_free_stat);
}
spin_unlock_irqrestore(&priv->low_lock, flags);
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
@@ -6440,8 +6096,6 @@
int registered = 0;
u32 val;
- IPW_DEBUG_INFO("enter\n");
-
mem_start = pci_resource_start(pci_dev, 0);
mem_len = pci_resource_len(pci_dev, 0);
mem_flags = pci_resource_flags(pci_dev, 0);
@@ -6589,8 +6243,6 @@
ipw2100_start_scan(priv);
}
- IPW_DEBUG_INFO("exit\n");
-
priv->status |= STATUS_INITIALIZED;
up(&priv->action_sem);
@@ -6644,10 +6296,9 @@
dev = priv->net_dev;
sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
-#ifdef CONFIG_PM
if (ipw2100_firmware.version)
ipw2100_release_firmware(priv, &ipw2100_firmware);
-#endif
+
/* Take down the hardware */
ipw2100_down(priv);
@@ -6680,17 +6331,11 @@
pci_release_regions(pci_dev);
pci_disable_device(pci_dev);
-
- IPW_DEBUG_INFO("exit\n");
}
#ifdef CONFIG_PM
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
-static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
-#else
static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
-#endif
{
struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
struct net_device *dev = priv->net_dev;
@@ -6707,17 +6352,9 @@
/* Remove the PRESENT state of the device */
netif_device_detach(dev);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
- pci_save_state(pci_dev, priv->pm_state);
-#else
pci_save_state(pci_dev);
-#endif
pci_disable_device (pci_dev);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
- pci_set_power_state(pci_dev, state);
-#else
pci_set_power_state(pci_dev, PCI_D3hot);
-#endif
up(&priv->action_sem);
@@ -6738,17 +6375,9 @@
IPW_DEBUG_INFO("%s: Coming out of suspend...\n",
dev->name);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
- pci_set_power_state(pci_dev, 0);
-#else
pci_set_power_state(pci_dev, PCI_D0);
-#endif
pci_enable_device(pci_dev);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
- pci_restore_state(pci_dev, priv->pm_state);
-#else
pci_restore_state(pci_dev);
-#endif
/*
* Suspend/Resume resets the PCI configuration space, so we have to
@@ -8295,8 +7924,6 @@
down(&priv->action_sem);
- IPW_DEBUG_WX("enter\n");
-
up(&priv->action_sem);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
Only in linux-mm/drivers/net/wireless: ipw2100.c.bad
Only in linux-mm/drivers/net/wireless: ipw2100.c.good
--- clean-mm/drivers/net/wireless/ipw2100.h 2005-05-11 22:00:02.000000000 +0200
+++ linux-mm/drivers/net/wireless/ipw2100.h 2005-05-13 00:44:39.000000000 +0200
@@ -44,30 +44,6 @@
#include <linux/workqueue.h>
-#ifndef IRQ_NONE
-typedef void irqreturn_t;
-#define IRQ_NONE
-#define IRQ_HANDLED
-#define IRQ_RETVAL(x)
-#endif
-
-#if WIRELESS_EXT < 17
-#define IW_QUAL_QUAL_INVALID 0x10
-#define IW_QUAL_LEVEL_INVALID 0x20
-#define IW_QUAL_NOISE_INVALID 0x40
-#endif
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) )
-#define pci_dma_sync_single_for_cpu pci_dma_sync_single
-#define pci_dma_sync_single_for_device pci_dma_sync_single
-#endif
-
-#ifndef HAVE_FREE_NETDEV
-#define free_netdev(x) kfree(x)
-#endif
-
-
-
struct ipw2100_priv;
struct ipw2100_tx_packet;
struct ipw2100_rx_packet;
@@ -167,15 +143,6 @@
#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
-
-#define VERIFY(f) \
-{ \
- int status = 0; \
- status = f; \
- if(status) \
- return status; \
-}
-
enum {
IPW_HW_STATE_DISABLED = 1,
IPW_HW_STATE_ENABLED = 0
@@ -210,8 +177,6 @@
} info;
} __attribute__ ((packed));
-#define IPW_BUFDESC_LAST_FRAG 0
-
struct ipw2100_bd {
u32 host_addr;
u32 buf_length;
@@ -355,7 +320,7 @@
u16 fragment_size;
} __attribute__ ((packed));
-// Host command data structure
+/* Host command data structure */
struct host_command {
u32 host_command; // COMMAND ID
u32 host_command1; // COMMAND ID
@@ -473,13 +438,8 @@
/* Power management code: enable or disable? */
enum {
-#ifdef CONFIG_PM
IPW2100_PM_DISABLED = 0,
PM_STATE_SIZE = 16,
-#else
- IPW2100_PM_DISABLED = 1,
- PM_STATE_SIZE = 0,
-#endif
};
#define STATUS_POWERED (1<<0)
@@ -648,9 +608,6 @@
struct semaphore adapter_sem;
wait_queue_head_t wait_command_queue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
- u32 pm_state[PM_STATE_SIZE];
-#endif
};
@@ -701,7 +658,7 @@
#define MSDU_TX_RATES 62
-// Rogue AP Detection
+/* Rogue AP Detection */
#define SET_STATION_STAT_BITS 64
#define CLEAR_STATIONS_STAT_BITS 65
#define LEAP_ROGUE_MODE 66 //TODO tbw replaced by CFG_LEAP_ROGUE_AP
@@ -711,25 +668,16 @@
-// system configuration bit mask:
-//#define IPW_CFG_ANTENNA_SETTING 0x03
-//#define IPW_CFG_ANTENNA_A 0x01
-//#define IPW_CFG_ANTENNA_B 0x02
+/* system configuration bit mask: */
#define IPW_CFG_MONITOR 0x00004
-//#define IPW_CFG_TX_STATUS_ENABLE 0x00008
#define IPW_CFG_PREAMBLE_AUTO 0x00010
#define IPW_CFG_IBSS_AUTO_START 0x00020
-//#define IPW_CFG_KERBEROS_ENABLE 0x00040
#define IPW_CFG_LOOPBACK 0x00100
-//#define IPW_CFG_WNMP_PING_PASS 0x00200
-//#define IPW_CFG_DEBUG_ENABLE 0x00400
#define IPW_CFG_ANSWER_BCSSID_PROBE 0x00800
-//#define IPW_CFG_BT_PRIORITY 0x01000
#define IPW_CFG_BT_SIDEBAND_SIGNAL 0x02000
#define IPW_CFG_802_1x_ENABLE 0x04000
#define IPW_CFG_BSS_MASK 0x08000
#define IPW_CFG_IBSS_MASK 0x10000
-//#define IPW_CFG_DYNAMIC_CW 0x10000
#define IPW_SCAN_NOASSOCIATE (1<<0)
#define IPW_SCAN_MIXED_CELL (1<<1)
@@ -761,41 +709,6 @@
#define IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX \
(IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND)
-
-#if 0
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x00)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x04)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x08)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0c)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x10)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x14)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x18)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x1c)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x80)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x84)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x88)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x8c)
-
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_BASE(QueueNum) \
- (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + (QueueNum<<3))
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE(QueueNum) \
- (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0004+(QueueNum<<3))
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX(QueueNum) \
- (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0080+(QueueNum<<2))
-
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_WRITE_INDEX \
- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x00)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_WRITE_INDEX \
- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x04)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_WRITE_INDEX \
- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x08)
-#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_WRITE_INDEX \
- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x0c)
-#define IPW_MEM_HOST_SHARED_SLAVE_MODE_INT_REGISTER \
- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x78)
-
-#endif
-
#define IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x180)
#define IPW_MEM_HOST_SHARED_ORDINALS_TABLE_2 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x184)
@@ -913,7 +826,7 @@
} rx_data;
} __attribute__ ((packed));
-// Bit 0-7 are for 802.11b tx rates - . Bit 5-7 are reserved
+/* Bit 0-7 are for 802.11b tx rates - . Bit 5-7 are reserved */
#define TX_RATE_1_MBIT 0x0001
#define TX_RATE_2_MBIT 0x0002
#define TX_RATE_5_5_MBIT 0x0004
@@ -1193,7 +1106,6 @@
IPW_ORD_UCODE_VERSION, // Ucode Version
IPW_ORD_HW_RF_SWITCH_STATE = 214, // HW RF Kill Switch State
} ORDINALTABLE1;
-//ENDOF TABLE1
// ordinal table 2
// Variable length data:
--
Boycott Kodak -- for their patent abuse against Java.
^ permalink raw reply
* Re: issue with new TCP TSO stuff
From: David S. Miller @ 2005-05-12 22:52 UTC (permalink / raw)
To: herbert; +Cc: netdev
In-Reply-To: <20050512221046.GA22136@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Subject: Re: issue with new TCP TSO stuff
Date: Fri, 13 May 2005 08:10:46 +1000
> Nevermind, you're comparing to the existing TSO implementation.
> So how big exactly is the slowdown?
The "scp largefile dest:" test case went down from 4.6MB/sec
to 4.3MB/sec when I enable TSO on the tg3 device with the
new TSO code.
So that drop is relative to non-TSO. That's how I knew there
was some trouble. TSO should definitely not have more overhead
that non-TSO.
For a clean transfer bulk transfer which is not application
limited like scp is, we get full line rate. But that doesn't
show how expensive TSO is, since the link is the bottleneck
not the cpu.
> This just occured to me, what about NETIF_F_SKBLIST?
Sounds ok.
^ permalink raw reply
* Re: issue with new TCP TSO stuff
From: Herbert Xu @ 2005-05-12 23:10 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050512.155230.132927874.davem@davemloft.net>
On Thu, May 12, 2005 at 03:52:30PM -0700, David S. Miller wrote:
>
> The "scp largefile dest:" test case went down from 4.6MB/sec
> to 4.3MB/sec when I enable TSO on the tg3 device with the
> new TSO code.
OK, I'm sure we can optimise the code so that it beats the
non-TSO case.
However, I think you're right that this does have some fundamental
overheads compared to the existing TSO code which we can't remove.
More specifically, the existing TSO code really does avoid
segmentation in that no MTU-sized skb's are allocated unless
the congestion window requires that to be done. The new code
will always allocate MTU-sized skb's no matter what.
The ideal solution should bring the best of both worlds :) That is,
no segmentation on output unless required by the congestion window,
while at the same time avoiding the tcp_skb_pcount logic.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: issue with new TCP TSO stuff
From: David S. Miller @ 2005-05-12 23:24 UTC (permalink / raw)
To: herbert; +Cc: netdev
In-Reply-To: <20050512231038.GA22440@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Subject: Re: issue with new TCP TSO stuff
Date: Fri, 13 May 2005 09:10:38 +1000
> However, I think you're right that this does have some fundamental
> overheads compared to the existing TSO code which we can't remove.
>
> More specifically, the existing TSO code really does avoid
> segmentation in that no MTU-sized skb's are allocated unless
> the congestion window requires that to be done. The new code
> will always allocate MTU-sized skb's no matter what.
>
> The ideal solution should bring the best of both worlds :) That is,
> no segmentation on output unless required by the congestion window,
> while at the same time avoiding the tcp_skb_pcount logic.
Right.
Ok, the two true downfalls of the current TSO code are:
1) It does not attempt to predict what the CWND will
be at packet output time. So smaller than ideal
TSO frames are built.
2) Packet loss is not handled gracefully, in fact TSO
is disabled when this happens :-)
So, I'm mentioning this because it may end up being better to try and
solve those two problems instead of going to my new stuff.
#2 could be handled by down-sizing TSO frames when packet loss occurs.
Ie. tcp_retransmit_skb() or whatever will segmentize a TSO packet
which is within the sequence it is trying to retransmit. Implementing
this is non- trivial mostly due to the fact that it has to work handle
GFP_ATOMIC memory failures and also get all the pcount crap correct.
#1 is more tricky, and is the main reason I explored the "TSO
Reloaded" idea. I wonder if we could just build enormous TSO frames
_always_. We pass down these huge things to the output path, with a
struct sk_buff local offset and size. That way, if the packet is too
large for the congestion window, we're fine, we just set the offset
and size appropriately. I think the tcp_snd_test() simplifications
made by my TSO Reloaded patch would help a lot here. The send test is
logically now split to it's two tests 1) whether to send anything at
all, and 2) once #1 passes, how many such packets.
This would be a sort of super-TSO that would do less segmenting work
than even a "perfect" TSO segmenter would.
I'm still not sure which approach is best, just throwing around some
ideas.
^ permalink raw reply
* Re: Questions wrt QoS code on Linux
From: Thomas Graf @ 2005-05-12 23:32 UTC (permalink / raw)
To: Jonathan Day; +Cc: netdev
In-Reply-To: <20050512190721.17518.qmail@web31508.mail.mud.yahoo.com>
* Jonathan Day <20050512190721.17518.qmail@web31508.mail.mud.yahoo.com> 2005-05-12 12:07
> You've actually got another bit in there which
> determines the ordering of the packets. a FIFO queue
> won't be ordered the same as a PRIO queue, for
> example.
I don't see the point why we should draw a line between
something like PRIO and CBQ, I would agree that dsmark
should be splitted though.
> A completely seperate stage is then needed to actually
> gather the packets from the queue(s). You might drain
> one queue completely before moving onto the next, you
> might work in a round-robin manner, you might even
> give a queue a fixed timeslice and grab as many
> packets as possible within that slice before moving
> on.
a) The qdisc _must_ be able to define the ordering, otherwise
we cannot do rate limiting correctly.
b) You definitely don't want reordering inside flows and the
qdisc is the only player that is aware of the right ordering.
> An additional section handles the case where the
> network is overloaded. You can drop packets early, by
> using systems like RED, BLUE, GREEN or BLACK. (Of
> these, only RED and the variant GRED are in Linux at
> the moment.)
The current RED implementation uses a queue and its length
as criteria for the congestion probability. However, I do
agree that in theory this should be implemented differently,
the detection and marking should take place before the
queue possibly via actions. This would also easly allow for
(colored) TSW and EWMA rate estimators to be put in front.
Surely everyone can agree that there is potential in this
area and I hope someone brave stands up one day doing all
the work.
> At present, the Linux QoS menu is confusing. CBQ is
> listed as a packet scheduler, when it in fact queues
> the packets, rather than schedules them. RED is marked
> as a queue, whereas it really filters, it doesn't
> queue.
The menu really can be improved and I think such a patch
would get accepted, although please leave the qdiscs
alone for now. ;->
> 1. Rename the sched directory to qos
I don't see any improvement comming along with
change as well.
> 2. Add a sched subdirectory and move the schedulers
> into it
> 3. Add a queue subdirectory and move the queue
> handlers into it
> 4. Add a classifier subdirectory and move the packet
> classifiers into it
> 5. Add a processor subdirectory and move all code for
> processing packets (such as RED) into it
I think the (sch_|cls_|em_) prefixes are just fine
for now.
^ permalink raw reply
* Re: issue with new TCP TSO stuff
From: Herbert Xu @ 2005-05-12 23:52 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050512.162426.75782784.davem@davemloft.net>
On Thu, May 12, 2005 at 04:24:26PM -0700, David S. Miller wrote:
>
> Ok, the two true downfalls of the current TSO code are:
You're spot on.
> #2 could be handled by down-sizing TSO frames when packet loss occurs.
> Ie. tcp_retransmit_skb() or whatever will segmentize a TSO packet
> which is within the sequence it is trying to retransmit. Implementing
> this is non- trivial mostly due to the fact that it has to work handle
> GFP_ATOMIC memory failures and also get all the pcount crap correct.
I think most of the code to do that might already be there. Pity
we'll have to keep track of the pcount though.
> #1 is more tricky, and is the main reason I explored the "TSO
> Reloaded" idea. I wonder if we could just build enormous TSO frames
> _always_. We pass down these huge things to the output path, with a
I agree that this is the way to go.
> and size appropriately. I think the tcp_snd_test() simplifications
> made by my TSO Reloaded patch would help a lot here. The send test is
> logically now split to it's two tests 1) whether to send anything at
> all, and 2) once #1 passes, how many such packets.
That was another one of my comments to your patch :) I was going to
suggest that we move the cwnd/in_flight loop from tcp_snd_test to
emit_send_queue.
> This would be a sort of super-TSO that would do less segmenting work
> than even a "perfect" TSO segmenter would.
>
> I'm still not sure which approach is best, just throwing around some
> ideas.
On paper your new super-TSO approach sounds the best. However, I
suppose we won't know for sure until we try :)
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [2.6 patch] drivers/net/hamradio/baycom_epp.c: cleanups
From: Adrian Bunk @ 2005-05-13 0:47 UTC (permalink / raw)
To: Andrew Morton; +Cc: sailer, linux-kernel, jgarzik, netdev
The times when tricky goto's produced better codes are long gone.
This patch should express the same in a better way.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
---
This patch was already sent on:
- 30 Apr 2005
- 20 Apr 2005
drivers/net/hamradio/baycom_epp.c | 126 ++++++++----------------------
1 files changed, 36 insertions(+), 90 deletions(-)
--- linux-2.6.12-rc2-mm3/drivers/net/hamradio/baycom_epp.c.old 2005-04-20 16:18:47.000000000 +0200
+++ linux-2.6.12-rc2-mm3/drivers/net/hamradio/baycom_epp.c 2005-04-20 17:14:36.000000000 +0200
@@ -374,29 +374,6 @@
}
/* --------------------------------------------------------------------- */
-/*
- * high performance HDLC encoder
- * yes, it's ugly, but generates pretty good code
- */
-
-#define ENCODEITERA(j) \
-({ \
- if (!(notbitstream & (0x1f0 << j))) \
- goto stuff##j; \
- encodeend##j: ; \
-})
-
-#define ENCODEITERB(j) \
-({ \
- stuff##j: \
- bitstream &= ~(0x100 << j); \
- bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | \
- ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); \
- numbit++; \
- notbitstream = ~bitstream; \
- goto encodeend##j; \
-})
-
static void encode_hdlc(struct baycom_state *bc)
{
@@ -405,6 +382,7 @@
int pkt_len;
unsigned bitstream, notbitstream, bitbuf, numbit, crc;
unsigned char crcarr[2];
+ int j;
if (bc->hdlctx.bufcnt > 0)
return;
@@ -429,24 +407,14 @@
pkt_len--;
if (!pkt_len)
bp = crcarr;
- ENCODEITERA(0);
- ENCODEITERA(1);
- ENCODEITERA(2);
- ENCODEITERA(3);
- ENCODEITERA(4);
- ENCODEITERA(5);
- ENCODEITERA(6);
- ENCODEITERA(7);
- goto enditer;
- ENCODEITERB(0);
- ENCODEITERB(1);
- ENCODEITERB(2);
- ENCODEITERB(3);
- ENCODEITERB(4);
- ENCODEITERB(5);
- ENCODEITERB(6);
- ENCODEITERB(7);
- enditer:
+ for (j = 0; j < 8; j++)
+ if (unlikely(!(notbitstream & (0x1f0 << j)))) {
+ bitstream &= ~(0x100 << j);
+ bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) |
+ ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1);
+ numbit++;
+ notbitstream = ~bitstream;
+ }
numbit += 8;
while (numbit >= 8) {
*wp++ = bitbuf;
@@ -612,37 +580,6 @@
bc->stats.rx_packets++;
}
-#define DECODEITERA(j) \
-({ \
- if (!(notbitstream & (0x0fc << j))) /* flag or abort */ \
- goto flgabrt##j; \
- if ((bitstream & (0x1f8 << j)) == (0xf8 << j)) /* stuffed bit */ \
- goto stuff##j; \
- enditer##j: ; \
-})
-
-#define DECODEITERB(j) \
-({ \
- flgabrt##j: \
- if (!(notbitstream & (0x1fc << j))) { /* abort received */ \
- state = 0; \
- goto enditer##j; \
- } \
- if ((bitstream & (0x1fe << j)) != (0x0fc << j)) /* flag received */ \
- goto enditer##j; \
- if (state) \
- do_rxpacket(dev); \
- bc->hdlcrx.bufcnt = 0; \
- bc->hdlcrx.bufptr = bc->hdlcrx.buf; \
- state = 1; \
- numbits = 7-j; \
- goto enditer##j; \
- stuff##j: \
- numbits--; \
- bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); \
- goto enditer##j; \
-})
-
static int receive(struct net_device *dev, int cnt)
{
struct baycom_state *bc = netdev_priv(dev);
@@ -651,6 +588,7 @@
unsigned char tmp[128];
unsigned char *cp;
int cnt2, ret = 0;
+ int j;
numbits = bc->hdlcrx.numbits;
state = bc->hdlcrx.state;
@@ -671,24 +609,32 @@
bitbuf |= (*cp) << 8;
numbits += 8;
notbitstream = ~bitstream;
- DECODEITERA(0);
- DECODEITERA(1);
- DECODEITERA(2);
- DECODEITERA(3);
- DECODEITERA(4);
- DECODEITERA(5);
- DECODEITERA(6);
- DECODEITERA(7);
- goto enddec;
- DECODEITERB(0);
- DECODEITERB(1);
- DECODEITERB(2);
- DECODEITERB(3);
- DECODEITERB(4);
- DECODEITERB(5);
- DECODEITERB(6);
- DECODEITERB(7);
- enddec:
+ for (j = 0; j < 8; j++) {
+
+ /* flag or abort */
+ if (unlikely(!(notbitstream & (0x0fc << j)))) {
+
+ /* abort received */
+ if (!(notbitstream & (0x1fc << j)))
+ state = 0;
+
+ /* not flag received */
+ else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) {
+ if (state)
+ do_rxpacket(dev);
+ bc->hdlcrx.bufcnt = 0;
+ bc->hdlcrx.bufptr = bc->hdlcrx.buf;
+ state = 1;
+ numbits = 7-j;
+ }
+ }
+
+ /* stuffed bit */
+ else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) {
+ numbits--;
+ bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1);
+ }
+ }
while (state && numbits >= 8) {
if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) {
state = 0;
^ permalink raw reply
* Re: ipw2100: intrusive cleanups, working this time ;-)
From: James Ketrenos @ 2005-05-13 0:52 UTC (permalink / raw)
To: Pavel Machek; +Cc: netdev, kernel list, jbohac, jbenc
In-Reply-To: <20050512225026.GA2822@elf.ucw.cz>
Pavel Machek wrote:
>Hi!
>
>There's a lot to clean up in header file, too... And this time it
>actually works.
>
>Now, I'd like to clean it a bit more and then submit it to akpm for
>-mm series. Will someone hate me for doing that?
>
>
Initial look over the patch looks reasonable; no functionality changes,
just code reduction. That said, I would like to pass it through a quick
validation cycle before its picked up.
We submitted ipw2100-1.1.0 to netdev a month or so ago. I would like to
see it go in to -mm through the netdev tree. I'll ask our QA folks to
run this patch through a quick regression cycle here just to do a sanity
check on it. Assuming nothing comes up, and if Jeff hasn't merged the
ipw2100 code yet, I'll resubmit the ipw2100 driver w/ your patch applied.
Part of the process we have in place is to try and make sure that the
versions that get picked up by distros and the majority of users have a
'known' level of quality. As part of that, we only want to get changes
pushed to -mm and eventual mainline that have gone through regression
testing.
Sound workable?
Thanks,
James
> Pavel
>
>--- clean-mm/drivers/net/wireless/ipw2100.c 2005-05-11 22:00:02.000000000 +0200
>+++ linux-mm/drivers/net/wireless/ipw2100.c 2005-05-13 00:42:27.000000000 +0200
>@@ -106,7 +106,7 @@
>
> tx_pend_list : Holds used Tx buffers waiting to go into the TBD ring
> TAIL modified ipw2100_tx()
>- HEAD modified by X__ipw2100_tx_send_data()
>+ HEAD modified by ipw2100_tx_send_data()
>
> msg_free_list : Holds pre-allocated Msg (Command) buffers
> TAIL modified in __ipw2100_tx_process()
>@@ -114,7 +114,7 @@
>
> msg_pend_list : Holds used Msg buffers waiting to go into the TBD ring
> TAIL modified in ipw2100_hw_send_command()
>- HEAD modified in X__ipw2100_tx_send_commands()
>+ HEAD modified in ipw2100_tx_send_commands()
>
> The flow of data on the TX side is as follows:
>
>@@ -150,7 +150,6 @@
> #include <linux/skbuff.h>
> #include <asm/uaccess.h>
> #include <asm/io.h>
>-#define __KERNEL_SYSCALLS__
> #include <linux/fs.h>
> #include <linux/mm.h>
> #include <linux/slab.h>
>@@ -174,11 +173,6 @@
> #define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
>
>
>-/* Debugging stuff */
>-#ifdef CONFIG_IPW_DEBUG
>-#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
>-#endif
>-
> MODULE_DESCRIPTION(DRV_DESCRIPTION);
> MODULE_VERSION(DRV_VERSION);
> MODULE_AUTHOR(DRV_COPYRIGHT);
>@@ -189,9 +183,7 @@
> static int channel = 0;
> static int associate = 1;
> static int disable = 0;
>-#ifdef CONFIG_PM
> static struct ipw2100_fw ipw2100_firmware;
>-#endif
>
> #include <linux/moduleparam.h>
> module_param(debug, int, 0444);
>@@ -286,8 +278,8 @@
>
>
> /* Pre-decl until we get the code solid and then we can clean it up */
>-static void X__ipw2100_tx_send_commands(struct ipw2100_priv *priv);
>-static void X__ipw2100_tx_send_data(struct ipw2100_priv *priv);
>+static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
>+static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
> static int ipw2100_adapter_setup(struct ipw2100_priv *priv);
>
> static void ipw2100_queues_initialize(struct ipw2100_priv *priv);
>@@ -735,8 +727,8 @@
> list_add_tail(element, &priv->msg_pend_list);
> INC_STAT(&priv->msg_pend_stat);
>
>- X__ipw2100_tx_send_commands(priv);
>- X__ipw2100_tx_send_data(priv);
>+ ipw2100_tx_send_commands(priv);
>+ ipw2100_tx_send_data(priv);
>
> spin_unlock_irqrestore(&priv->low_lock, flags);
>
>@@ -915,12 +907,10 @@
> if (i == 10000)
> return -EIO; /* TODO: better error value */
>
>-//#if CONFIG_IPW2100_D0ENABLED
> /* set D0 standby bit */
> read_register(priv->net_dev, IPW_REG_GP_CNTRL, &r);
> write_register(priv->net_dev, IPW_REG_GP_CNTRL,
> r | IPW_AUX_HOST_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
>-//#endif
>
> return 0;
> }
>@@ -941,11 +931,6 @@
> u32 address;
> int err;
>
>-#ifndef CONFIG_PM
>- /* Fetch the firmware and microcode */
>- struct ipw2100_fw ipw2100_firmware;
>-#endif
>-
> if (priv->fatal_error) {
> IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
> "fatal error %d. Interface must be brought down.\n",
>@@ -953,7 +938,6 @@
> return -EINVAL;
> }
>
>-#ifdef CONFIG_PM
> if (!ipw2100_firmware.version) {
> err = ipw2100_get_firmware(priv, &ipw2100_firmware);
> if (err) {
>@@ -963,15 +947,6 @@
> goto fail;
> }
> }
>-#else
>- err = ipw2100_get_firmware(priv, &ipw2100_firmware);
>- if (err) {
>- IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
>- priv->net_dev->name, err);
>- priv->fatal_error = IPW2100_ERR_FW_LOAD;
>- goto fail;
>- }
>-#endif
> priv->firmware_version = ipw2100_firmware.version;
>
> /* s/w reset and clock stabilization */
>@@ -1026,18 +1001,6 @@
> goto fail;
> }
>
>-#ifndef CONFIG_PM
>- /*
>- * When the .resume method of the driver is called, the other
>- * part of the system, i.e. the ide driver could still stay in
>- * the suspend stage. This prevents us from loading the firmware
>- * from the disk. --YZ
>- */
>-
>- /* free any storage allocated for firmware image */
>- ipw2100_release_firmware(priv, &ipw2100_firmware);
>-#endif
>-
> /* zero out Domain 1 area indirectly (Si requirement) */
> for (address = IPW_HOST_FW_SHARED_AREA0;
> address < IPW_HOST_FW_SHARED_AREA0_END; address += 4)
>@@ -1083,8 +1046,6 @@
> {
> struct ipw2100_ordinals *ord = &priv->ordinals;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> read_register(priv->net_dev, IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1,
> &ord->table1_addr);
>
>@@ -1095,10 +1056,6 @@
> read_nic_dword(priv->net_dev, ord->table2_addr, &ord->table2_size);
>
> ord->table2_size &= 0x0000FFFF;
>-
>- IPW_DEBUG_INFO("table 1 size: %d\n", ord->table1_size);
>- IPW_DEBUG_INFO("table 2 size: %d\n", ord->table2_size);
>- IPW_DEBUG_INFO("exit\n");
> }
>
> static inline void ipw2100_hw_set_gpio(struct ipw2100_priv *priv)
>@@ -1117,7 +1074,6 @@
> {
> #define MAX_RF_KILL_CHECKS 5
> #define RF_KILL_CHECK_DELAY 40
>-#define RF_KILL_CHECK_THRESHOLD 3
>
> unsigned short value = 0;
> u32 reg = 0;
>@@ -1198,8 +1154,6 @@
> int i;
> u32 inta, inta_mask, gpio;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> if (priv->status & STATUS_RUNNING)
> return 0;
>
>@@ -1286,9 +1240,6 @@
>
> /* The adapter has been reset; we are not associated */
> priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
>-
>- IPW_DEBUG_INFO("exit\n");
>-
> return 0;
> }
>
>@@ -1598,8 +1549,6 @@
> };
> int err;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> IPW_DEBUG_SCAN("setting scan options\n");
>
> cmd.host_command_parameters[0] = 0;
>@@ -1643,8 +1592,6 @@
> return 0;
> }
>
>- IPW_DEBUG_INFO("enter\n");
>-
> /* Not clearing here; doing so makes iwlist always return nothing...
> *
> * We should modify the table logic to use aging tables vs. clearing
>@@ -1657,8 +1604,6 @@
> if (err)
> priv->status &= ~STATUS_SCANNING;
>
>- IPW_DEBUG_INFO("exit\n");
>-
> return err;
> }
>
>@@ -2285,18 +2230,10 @@
> * The size of the constructed ethernet
> *
> */
>-#ifdef CONFIG_IPW2100_RX_DEBUG
>-u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
>-#endif
>
> static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
> int i)
> {
>-#ifdef CONFIG_IPW_DEBUG_C3
>- struct ipw2100_status *status = &priv->status_queue.drv[i];
>- u32 match, reg;
>- int j;
>-#endif
> #ifdef ACPI_CSTATE_LIMIT_DEFINED
> int limit;
> #endif
>@@ -2314,35 +2251,6 @@
> }
> #endif
>
>-#ifdef CONFIG_IPW_DEBUG_C3
>- /* Halt the fimrware so we can get a good image */
>- write_register(priv->net_dev, IPW_REG_RESET_REG,
>- IPW_AUX_HOST_RESET_REG_STOP_MASTER);
>- j = 5;
>- do {
>- udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY);
>- read_register(priv->net_dev, IPW_REG_RESET_REG, ®);
>-
>- if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
>- break;
>- } while (j--);
>-
>- match = ipw2100_match_buf(priv, (u8*)status,
>- sizeof(struct ipw2100_status),
>- SEARCH_SNAPSHOT);
>- if (match < SEARCH_SUCCESS)
>- IPW_DEBUG_INFO("%s: DMA status match in Firmware at "
>- "offset 0x%06X, length %d:\n",
>- priv->net_dev->name, match,
>- sizeof(struct ipw2100_status));
>- else
>- IPW_DEBUG_INFO("%s: No DMA status match in "
>- "Firmware.\n", priv->net_dev->name);
>-
>- printk_buf((u8*)priv->status_queue.drv,
>- sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
>-#endif
>-
> priv->fatal_error = IPW2100_ERR_C3_CORRUPTION;
> priv->ieee->stats.rx_errors++;
> schedule_reset(priv);
>@@ -2394,19 +2302,7 @@
>
> skb_put(packet->skb, status->frame_size);
>
>-#ifdef CONFIG_IPW2100_RX_DEBUG
>- /* Make a copy of the frame so we can dump it to the logs if
>- * ieee80211_rx fails */
>- memcpy(packet_data, packet->skb->data,
>- min(status->frame_size, IPW_RX_NIC_BUFFER_LENGTH));
>-#endif
>-
> if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
>-#ifdef CONFIG_IPW2100_RX_DEBUG
>- IPW_DEBUG_DROP("%s: Non consumed packet:\n",
>- priv->net_dev->name);
>- printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
>-#endif
> priv->ieee->stats.rx_errors++;
>
> /* ieee80211_rx failed, so it didn't free the SKB */
>@@ -2847,7 +2743,7 @@
> }
>
>
>-static void X__ipw2100_tx_send_commands(struct ipw2100_priv *priv)
>+static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
> {
> struct list_head *element;
> struct ipw2100_tx_packet *packet;
>@@ -2915,10 +2811,10 @@
>
>
> /*
>- * X__ipw2100_tx_send_data
>+ * ipw2100_tx_send_data
> *
> */
>-static void X__ipw2100_tx_send_data(struct ipw2100_priv *priv)
>+static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
> {
> struct list_head *element;
> struct ipw2100_tx_packet *packet;
>@@ -3133,8 +3029,8 @@
> IPW2100_INTA_TX_TRANSFER);
>
> __ipw2100_tx_complete(priv);
>- X__ipw2100_tx_send_commands(priv);
>- X__ipw2100_tx_send_data(priv);
>+ ipw2100_tx_send_commands(priv);
>+ ipw2100_tx_send_data(priv);
> }
>
> if (inta & IPW2100_INTA_TX_COMPLETE) {
>@@ -3192,8 +3088,6 @@
> ipw2100_enable_interrupts(priv);
>
> spin_unlock_irqrestore(&priv->low_lock, flags);
>-
>- IPW_DEBUG_ISR("exit\n");
> }
>
>
>@@ -3285,7 +3179,7 @@
> list_add_tail(element, &priv->tx_pend_list);
> INC_STAT(&priv->tx_pend_stat);
>
>- X__ipw2100_tx_send_data(priv);
>+ ipw2100_tx_send_data(priv);
>
> spin_unlock_irqrestore(&priv->low_lock, flags);
> return 0;
>@@ -3662,96 +3556,6 @@
> }
> static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
>
>-
>-static ssize_t show_memory(struct device *d, char *buf)
>-{
>- struct ipw2100_priv *priv = dev_get_drvdata(d);
>- struct net_device *dev = priv->net_dev;
>- static unsigned long loop = 0;
>- int len = 0;
>- u32 buffer[4];
>- int i;
>- char line[81];
>-
>- if (loop >= 0x30000)
>- loop = 0;
>-
>- /* sysfs provides us PAGE_SIZE buffer */
>- while (len < PAGE_SIZE - 128 && loop < 0x30000) {
>-
>- if (priv->snapshot[0]) for (i = 0; i < 4; i++)
>- buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
>- else for (i = 0; i < 4; i++)
>- read_nic_dword(dev, loop + i * 4, &buffer[i]);
>-
>- if (priv->dump_raw)
>- len += sprintf(buf + len,
>- "%c%c%c%c"
>- "%c%c%c%c"
>- "%c%c%c%c"
>- "%c%c%c%c",
>- ((u8*)buffer)[0x0],
>- ((u8*)buffer)[0x1],
>- ((u8*)buffer)[0x2],
>- ((u8*)buffer)[0x3],
>- ((u8*)buffer)[0x4],
>- ((u8*)buffer)[0x5],
>- ((u8*)buffer)[0x6],
>- ((u8*)buffer)[0x7],
>- ((u8*)buffer)[0x8],
>- ((u8*)buffer)[0x9],
>- ((u8*)buffer)[0xa],
>- ((u8*)buffer)[0xb],
>- ((u8*)buffer)[0xc],
>- ((u8*)buffer)[0xd],
>- ((u8*)buffer)[0xe],
>- ((u8*)buffer)[0xf]);
>- else
>- len += sprintf(buf + len, "%s\n",
>- snprint_line(line, sizeof(line),
>- (u8*)buffer, 16, loop));
>- loop += 16;
>- }
>-
>- return len;
>-}
>-
>-static ssize_t store_memory(struct device *d, const char *buf, size_t count)
>-{
>- struct ipw2100_priv *priv = dev_get_drvdata(d);
>- struct net_device *dev = priv->net_dev;
>- const char *p = buf;
>-
>- if (count < 1)
>- return count;
>-
>- if (p[0] == '1' ||
>- (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
>- IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
>- dev->name);
>- priv->dump_raw = 1;
>-
>- } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
>- tolower(p[1]) == 'f')) {
>- IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
>- dev->name);
>- priv->dump_raw = 0;
>-
>- } else if (tolower(p[0]) == 'r') {
>- IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n",
>- dev->name);
>- ipw2100_snapshot_free(priv);
>-
>- } else
>- IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
>- "reset = clear memory snapshot\n",
>- dev->name);
>-
>- return count;
>-}
>-static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
>-
>-
> static ssize_t show_ordinals(struct device *d, char *buf)
> {
> struct ipw2100_priv *priv = dev_get_drvdata(d);
>@@ -3837,11 +3641,9 @@
>
> priv->ieee->iw_mode = mode;
>
>-#ifdef CONFIG_PM
> /* Indicate ipw2100_download_firmware download firmware
> * from disk instead of memory. */
> ipw2100_firmware.version = 0;
>-#endif
>
> printk(KERN_INFO "%s: Reseting on mode change.\n",
> priv->net_dev->name);
>@@ -4030,8 +3832,6 @@
> unsigned long val;
> char *p = buffer;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> strncpy(buffer, buf, len);
> buffer[len] = 0;
>
>@@ -4049,8 +3849,6 @@
> priv->ieee->scan_age = val;
> IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
> }
>-
>- IPW_DEBUG_INFO("exit\n");
> return len;
> }
> static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
>@@ -4117,7 +3915,6 @@
> &dev_attr_stats.attr,
> &dev_attr_internals.attr,
> &dev_attr_bssinfo.attr,
>- &dev_attr_memory.attr,
> &dev_attr_scan_age.attr,
> &dev_attr_fatal_error.attr,
> &dev_attr_rf_kill.attr,
>@@ -4136,8 +3933,6 @@
> {
> struct ipw2100_status_queue *q = &priv->status_queue;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> q->size = entries * sizeof(struct ipw2100_status);
> q->drv = (struct ipw2100_status *)pci_alloc_consistent(
> priv->pci_dev, q->size, &q->nic);
>@@ -4148,31 +3943,22 @@
> }
>
> memset(q->drv, 0, q->size);
>-
>- IPW_DEBUG_INFO("exit\n");
>-
> return 0;
> }
>
> static void status_queue_free(struct ipw2100_priv *priv)
> {
>- IPW_DEBUG_INFO("enter\n");
>-
> if (priv->status_queue.drv) {
> pci_free_consistent(
> priv->pci_dev, priv->status_queue.size,
> priv->status_queue.drv, priv->status_queue.nic);
> priv->status_queue.drv = NULL;
> }
>-
>- IPW_DEBUG_INFO("exit\n");
> }
>
> static int bd_queue_allocate(struct ipw2100_priv *priv,
> struct ipw2100_bd_queue *q, int entries)
> {
>- IPW_DEBUG_INFO("enter\n");
>-
> memset(q, 0, sizeof(struct ipw2100_bd_queue));
>
> q->entries = entries;
>@@ -4183,17 +3969,12 @@
> return -ENOMEM;
> }
> memset(q->drv, 0, q->size);
>-
>- IPW_DEBUG_INFO("exit\n");
>-
> return 0;
> }
>
> static void bd_queue_free(struct ipw2100_priv *priv,
> struct ipw2100_bd_queue *q)
> {
>- IPW_DEBUG_INFO("enter\n");
>-
> if (!q)
> return;
>
>@@ -4202,24 +3983,18 @@
> q->size, q->drv, q->nic);
> q->drv = NULL;
> }
>-
>- IPW_DEBUG_INFO("exit\n");
> }
>
> static void bd_queue_initialize(
> struct ipw2100_priv *priv, struct ipw2100_bd_queue * q,
> u32 base, u32 size, u32 r, u32 w)
> {
>- IPW_DEBUG_INFO("enter\n");
>-
> IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, q->nic);
>
> write_register(priv->net_dev, base, q->nic);
> write_register(priv->net_dev, size, q->entries);
> write_register(priv->net_dev, r, q->oldest);
> write_register(priv->net_dev, w, q->next);
>-
>- IPW_DEBUG_INFO("exit\n");
> }
>
> static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
>@@ -4243,8 +4018,6 @@
> void *v;
> dma_addr_t p;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
> if (err) {
> IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
>@@ -4299,8 +4072,6 @@
> {
> int i;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> /*
> * reinitialize packet info lists
> */
>@@ -4339,17 +4110,12 @@
> IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE,
> IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,
> IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX);
>-
>- IPW_DEBUG_INFO("exit\n");
>-
> }
>
> static void ipw2100_tx_free(struct ipw2100_priv *priv)
> {
> int i;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> bd_queue_free(priv, &priv->tx_queue);
>
> if (!priv->tx_buffers)
>@@ -4370,8 +4136,6 @@
>
> kfree(priv->tx_buffers);
> priv->tx_buffers = NULL;
>-
>- IPW_DEBUG_INFO("exit\n");
> }
>
>
>@@ -4380,8 +4144,6 @@
> {
> int i, j, err = -EINVAL;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> err = bd_queue_allocate(priv, &priv->rx_queue, RX_QUEUE_LENGTH);
> if (err) {
> IPW_DEBUG_INFO("failed bd_queue_allocate\n");
>@@ -4448,8 +4210,6 @@
>
> static void ipw2100_rx_initialize(struct ipw2100_priv *priv)
> {
>- IPW_DEBUG_INFO("enter\n");
>-
> priv->rx_queue.oldest = 0;
> priv->rx_queue.available = priv->rx_queue.entries - 1;
> priv->rx_queue.next = priv->rx_queue.entries - 1;
>@@ -4466,16 +4226,12 @@
> /* set up the status queue */
> write_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_STATUS_BASE,
> priv->status_queue.nic);
>-
>- IPW_DEBUG_INFO("exit\n");
> }
>
> static void ipw2100_rx_free(struct ipw2100_priv *priv)
> {
> int i;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> bd_queue_free(priv, &priv->rx_queue);
> status_queue_free(priv);
>
>@@ -4494,8 +4250,6 @@
>
> kfree(priv->rx_buffers);
> priv->rx_buffers = NULL;
>-
>- IPW_DEBUG_INFO("exit\n");
> }
>
> static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
>@@ -4536,8 +4290,6 @@
>
> IPW_DEBUG_HC("SET_MAC_ADDRESS\n");
>
>- IPW_DEBUG_INFO("enter\n");
>-
> if (priv->config & CFG_CUSTOM_MAC) {
> memcpy(cmd.host_command_parameters, priv->mac_addr,
> ETH_ALEN);
>@@ -4547,8 +4299,6 @@
> ETH_ALEN);
>
> err = ipw2100_hw_send_command(priv, &cmd);
>-
>- IPW_DEBUG_INFO("exit\n");
> return err;
> }
>
>@@ -4805,47 +4555,6 @@
> return 0;
> }
>
>-#if 0
>-int ipw2100_set_fragmentation_threshold(struct ipw2100_priv *priv,
>- u32 threshold, int batch_mode)
>-{
>- struct host_command cmd = {
>- .host_command = FRAG_THRESHOLD,
>- .host_command_sequence = 0,
>- .host_command_length = 4,
>- .host_command_parameters[0] = 0,
>- };
>- int err;
>-
>- if (!batch_mode) {
>- err = ipw2100_disable_adapter(priv);
>- if (err)
>- return err;
>- }
>-
>- if (threshold == 0)
>- threshold = DEFAULT_FRAG_THRESHOLD;
>- else {
>- threshold = max(threshold, MIN_FRAG_THRESHOLD);
>- threshold = min(threshold, MAX_FRAG_THRESHOLD);
>- }
>-
>- cmd.host_command_parameters[0] = threshold;
>-
>- IPW_DEBUG_HC("FRAG_THRESHOLD: %u\n", threshold);
>-
>- err = ipw2100_hw_send_command(priv, &cmd);
>-
>- if (!batch_mode)
>- ipw2100_enable_adapter(priv);
>-
>- if (!err)
>- priv->frag_threshold = threshold;
>-
>- return err;
>-}
>-#endif
>-
> int ipw2100_set_short_retry(struct ipw2100_priv *priv, u32 retry)
> {
> struct host_command cmd = {
>@@ -4935,8 +4644,6 @@
> int err;
> int len;
>
>- IPW_DEBUG_HC("DISASSOCIATION_BSSID\n");
>-
> len = ETH_ALEN;
> /* The Firmware currently ignores the BSSID and just disassociates from
> * the currently associated AP -- but in the off chance that a future
>@@ -4950,37 +4657,6 @@
> }
> #endif
>
>-/*
>- * Pseudo code for setting up wpa_frame:
>- */
>-#if 0
>-void x(struct ieee80211_assoc_frame *wpa_assoc)
>-{
>- struct ipw2100_wpa_assoc_frame frame;
>- frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
>- IPW_WPA_LISTENINTERVAL |
>- IPW_WPA_AP_ADDRESS;
>- frame->capab_info = wpa_assoc->capab_info;
>- frame->lisen_interval = wpa_assoc->listent_interval;
>- memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
>-
>- /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
>- * setup here to test it with.
>- *
>- * Walk the IEs in the wpa_assoc and figure out the total size of all
>- * that data. Stick that into frame->var_ie_len. Then memcpy() all of
>- * the IEs from wpa_frame into frame.
>- */
>- frame->var_ie_len = calculate_ie_len(wpa_assoc);
>- memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
>-
>- ipw2100_set_wpa_ie(priv, &frame, 0);
>-}
>-#endif
>-
>-
>-
>-
> static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
> struct ipw2100_wpa_assoc_frame *, int)
> __attribute__ ((unused));
>@@ -4996,8 +4672,6 @@
> };
> int err;
>
>- IPW_DEBUG_HC("SET_WPA_IE\n");
>-
> if (!batch_mode) {
> err = ipw2100_disable_adapter(priv);
> if (err)
>@@ -5123,8 +4797,6 @@
>
> cmd.host_command_parameters[0] = interval;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
> if (!batch_mode) {
> err = ipw2100_disable_adapter(priv);
>@@ -5140,9 +4812,6 @@
> return err;
> }
> }
>-
>- IPW_DEBUG_INFO("exit\n");
>-
> return 0;
> }
>
>@@ -5502,8 +5171,6 @@
> int batch_mode = 1;
> u8 *bssid;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> err = ipw2100_disable_adapter(priv);
> if (err)
> return err;
>@@ -5512,9 +5179,6 @@
> err = ipw2100_set_channel(priv, priv->channel, batch_mode);
> if (err)
> return err;
>-
>- IPW_DEBUG_INFO("exit\n");
>-
> return 0;
> }
> #endif /* CONFIG_IPW2100_MONITOR */
>@@ -5591,9 +5255,6 @@
> if (err)
> return err;
> */
>-
>- IPW_DEBUG_INFO("exit\n");
>-
> return 0;
> }
>
>@@ -5656,8 +5317,6 @@
> struct list_head *element;
> struct ipw2100_tx_packet *packet;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> spin_lock_irqsave(&priv->low_lock, flags);
>
> if (priv->status & STATUS_ASSOCIATED)
>@@ -5679,9 +5338,6 @@
> INC_STAT(&priv->tx_free_stat);
> }
> spin_unlock_irqrestore(&priv->low_lock, flags);
>-
>- IPW_DEBUG_INFO("exit\n");
>-
> return 0;
> }
>
>@@ -6440,8 +6096,6 @@
> int registered = 0;
> u32 val;
>
>- IPW_DEBUG_INFO("enter\n");
>-
> mem_start = pci_resource_start(pci_dev, 0);
> mem_len = pci_resource_len(pci_dev, 0);
> mem_flags = pci_resource_flags(pci_dev, 0);
>@@ -6589,8 +6243,6 @@
> ipw2100_start_scan(priv);
> }
>
>- IPW_DEBUG_INFO("exit\n");
>-
> priv->status |= STATUS_INITIALIZED;
>
> up(&priv->action_sem);
>@@ -6644,10 +6296,9 @@
> dev = priv->net_dev;
> sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
>
>-#ifdef CONFIG_PM
> if (ipw2100_firmware.version)
> ipw2100_release_firmware(priv, &ipw2100_firmware);
>-#endif
>+
> /* Take down the hardware */
> ipw2100_down(priv);
>
>@@ -6680,17 +6331,11 @@
>
> pci_release_regions(pci_dev);
> pci_disable_device(pci_dev);
>-
>- IPW_DEBUG_INFO("exit\n");
> }
>
>
> #ifdef CONFIG_PM
>-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
>-static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
>-#else
> static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
>-#endif
> {
> struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
> struct net_device *dev = priv->net_dev;
>@@ -6707,17 +6352,9 @@
> /* Remove the PRESENT state of the device */
> netif_device_detach(dev);
>
>-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
>- pci_save_state(pci_dev, priv->pm_state);
>-#else
> pci_save_state(pci_dev);
>-#endif
> pci_disable_device (pci_dev);
>-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
>- pci_set_power_state(pci_dev, state);
>-#else
> pci_set_power_state(pci_dev, PCI_D3hot);
>-#endif
>
> up(&priv->action_sem);
>
>@@ -6738,17 +6375,9 @@
> IPW_DEBUG_INFO("%s: Coming out of suspend...\n",
> dev->name);
>
>-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
>- pci_set_power_state(pci_dev, 0);
>-#else
> pci_set_power_state(pci_dev, PCI_D0);
>-#endif
> pci_enable_device(pci_dev);
>-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
>- pci_restore_state(pci_dev, priv->pm_state);
>-#else
> pci_restore_state(pci_dev);
>-#endif
>
> /*
> * Suspend/Resume resets the PCI configuration space, so we have to
>@@ -8295,8 +7924,6 @@
>
> down(&priv->action_sem);
>
>- IPW_DEBUG_WX("enter\n");
>-
> up(&priv->action_sem);
>
> wrqu.ap_addr.sa_family = ARPHRD_ETHER;
>Only in linux-mm/drivers/net/wireless: ipw2100.c.bad
>Only in linux-mm/drivers/net/wireless: ipw2100.c.good
>--- clean-mm/drivers/net/wireless/ipw2100.h 2005-05-11 22:00:02.000000000 +0200
>+++ linux-mm/drivers/net/wireless/ipw2100.h 2005-05-13 00:44:39.000000000 +0200
>@@ -44,30 +44,6 @@
>
> #include <linux/workqueue.h>
>
>-#ifndef IRQ_NONE
>-typedef void irqreturn_t;
>-#define IRQ_NONE
>-#define IRQ_HANDLED
>-#define IRQ_RETVAL(x)
>-#endif
>-
>-#if WIRELESS_EXT < 17
>-#define IW_QUAL_QUAL_INVALID 0x10
>-#define IW_QUAL_LEVEL_INVALID 0x20
>-#define IW_QUAL_NOISE_INVALID 0x40
>-#endif
>-
>-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) )
>-#define pci_dma_sync_single_for_cpu pci_dma_sync_single
>-#define pci_dma_sync_single_for_device pci_dma_sync_single
>-#endif
>-
>-#ifndef HAVE_FREE_NETDEV
>-#define free_netdev(x) kfree(x)
>-#endif
>-
>-
>-
> struct ipw2100_priv;
> struct ipw2100_tx_packet;
> struct ipw2100_rx_packet;
>@@ -167,15 +143,6 @@
> #define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
> #define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
>
>-
>-#define VERIFY(f) \
>-{ \
>- int status = 0; \
>- status = f; \
>- if(status) \
>- return status; \
>-}
>-
> enum {
> IPW_HW_STATE_DISABLED = 1,
> IPW_HW_STATE_ENABLED = 0
>@@ -210,8 +177,6 @@
> } info;
> } __attribute__ ((packed));
>
>-#define IPW_BUFDESC_LAST_FRAG 0
>-
> struct ipw2100_bd {
> u32 host_addr;
> u32 buf_length;
>@@ -355,7 +320,7 @@
> u16 fragment_size;
> } __attribute__ ((packed));
>
>-// Host command data structure
>+/* Host command data structure */
> struct host_command {
> u32 host_command; // COMMAND ID
> u32 host_command1; // COMMAND ID
>@@ -473,13 +438,8 @@
>
> /* Power management code: enable or disable? */
> enum {
>-#ifdef CONFIG_PM
> IPW2100_PM_DISABLED = 0,
> PM_STATE_SIZE = 16,
>-#else
>- IPW2100_PM_DISABLED = 1,
>- PM_STATE_SIZE = 0,
>-#endif
> };
>
> #define STATUS_POWERED (1<<0)
>@@ -648,9 +608,6 @@
> struct semaphore adapter_sem;
>
> wait_queue_head_t wait_command_queue;
>-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
>- u32 pm_state[PM_STATE_SIZE];
>-#endif
> };
>
>
>@@ -701,7 +658,7 @@
> #define MSDU_TX_RATES 62
>
>
>-// Rogue AP Detection
>+/* Rogue AP Detection */
> #define SET_STATION_STAT_BITS 64
> #define CLEAR_STATIONS_STAT_BITS 65
> #define LEAP_ROGUE_MODE 66 //TODO tbw replaced by CFG_LEAP_ROGUE_AP
>@@ -711,25 +668,16 @@
>
>
>
>-// system configuration bit mask:
>-//#define IPW_CFG_ANTENNA_SETTING 0x03
>-//#define IPW_CFG_ANTENNA_A 0x01
>-//#define IPW_CFG_ANTENNA_B 0x02
>+/* system configuration bit mask: */
> #define IPW_CFG_MONITOR 0x00004
>-//#define IPW_CFG_TX_STATUS_ENABLE 0x00008
> #define IPW_CFG_PREAMBLE_AUTO 0x00010
> #define IPW_CFG_IBSS_AUTO_START 0x00020
>-//#define IPW_CFG_KERBEROS_ENABLE 0x00040
> #define IPW_CFG_LOOPBACK 0x00100
>-//#define IPW_CFG_WNMP_PING_PASS 0x00200
>-//#define IPW_CFG_DEBUG_ENABLE 0x00400
> #define IPW_CFG_ANSWER_BCSSID_PROBE 0x00800
>-//#define IPW_CFG_BT_PRIORITY 0x01000
> #define IPW_CFG_BT_SIDEBAND_SIGNAL 0x02000
> #define IPW_CFG_802_1x_ENABLE 0x04000
> #define IPW_CFG_BSS_MASK 0x08000
> #define IPW_CFG_IBSS_MASK 0x10000
>-//#define IPW_CFG_DYNAMIC_CW 0x10000
>
> #define IPW_SCAN_NOASSOCIATE (1<<0)
> #define IPW_SCAN_MIXED_CELL (1<<1)
>@@ -761,41 +709,6 @@
> #define IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX \
> (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND)
>
>-
>-#if 0
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x00)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x04)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x08)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0c)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x10)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x14)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x18)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x1c)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x80)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x84)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x88)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x8c)
>-
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_BASE(QueueNum) \
>- (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + (QueueNum<<3))
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE(QueueNum) \
>- (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0004+(QueueNum<<3))
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX(QueueNum) \
>- (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0080+(QueueNum<<2))
>-
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_WRITE_INDEX \
>- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x00)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_WRITE_INDEX \
>- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x04)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_WRITE_INDEX \
>- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x08)
>-#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_WRITE_INDEX \
>- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x0c)
>-#define IPW_MEM_HOST_SHARED_SLAVE_MODE_INT_REGISTER \
>- (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x78)
>-
>-#endif
>-
> #define IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x180)
> #define IPW_MEM_HOST_SHARED_ORDINALS_TABLE_2 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x184)
>
>@@ -913,7 +826,7 @@
> } rx_data;
> } __attribute__ ((packed));
>
>-// Bit 0-7 are for 802.11b tx rates - . Bit 5-7 are reserved
>+/* Bit 0-7 are for 802.11b tx rates - . Bit 5-7 are reserved */
> #define TX_RATE_1_MBIT 0x0001
> #define TX_RATE_2_MBIT 0x0002
> #define TX_RATE_5_5_MBIT 0x0004
>@@ -1193,7 +1106,6 @@
> IPW_ORD_UCODE_VERSION, // Ucode Version
> IPW_ORD_HW_RF_SWITCH_STATE = 214, // HW RF Kill Switch State
> } ORDINALTABLE1;
>-//ENDOF TABLE1
>
> // ordinal table 2
> // Variable length data:
>
>
>
^ permalink raw reply
* Lost subscribers to Airside and Lemon Jelly mailing lists
From: Apache @ 2005-05-13 1:27 UTC (permalink / raw)
To: netdev
Dear all,
We are contacting you from Airside, a design company based in London. Due to the failure of a web server and the host company back up, some subscribers to our mailing lists were lost.
Since then, however, the email addresses that were on the lists have been recovered, but annoyingly we have no idea who was subscribing to which list.
So we would very much appreciate if you could re-subscribe yourself appropriately from the website mailing lists provided below. If you choose to not re-subscribe, no problem and thanks for your patience.
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ
Lemon Jelly: http://www.airside.co.uk/redirect.php?mailing_history_id=63&user_id=631178&url=www.lemonjelly.ky
Airside: http://www.airside.co.uk/redirect.php?mailing_history_id=63&user_id=631178&url=www.airside.co.uk%2Fjoin%2Fsubscribe.html
Airside Shop: http://www.airside.co.uk/redirect.php?mailing_history_id=63&user_id=631178&url=www.airsideshop.com%2Finfo.php%3Fpage%3D12
Stitches: http://www.airside.co.uk/redirect.php?mailing_history_id=63&user_id=631178&url=www.welovestitches.com
Airside T-shirt Club: http://www.airside.co.uk/redirect.php?mailing_history_id=63&user_id=631178&url=www.airsideshop.com%2Fproducts.php%3Fpage%3D54%26archived%3Dall
MAG Anti Landmines Campaign Promotion: http://www.airside.co.uk/redirect.php?mailing_history_id=63&user_id=631178&url=www.airside.co.uk%2FMAG%2F
If you have received mail from any of the lists in the past month, you will not need to resubscribe.
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ
If you have any questions, please feel free to email us at <resubscribe@airside.co.uk>
If you want to check out who we are, visit our website at http://www.airside.co.uk/redirect.php?mailing_history_id=63&user_id=631178&url=www.airside.co.uk
Sincere apologies and sorry for the mass mailout, there will be no more emails sent to this list.
Yours faithfully
Alex Maclean
Director
-------------------------------------------------------
To unsubscribe from this mailing list, please visit
http://www.airside.co.uk/unsubscribe.php
^ permalink raw reply
* Perf data with recent tg3 patches
From: Arthur Kepner @ 2005-05-13 2:49 UTC (permalink / raw)
To: davem, mchan; +Cc: netdev
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2940 bytes --]
Several tg3 patches have been recently posted, and I've
collected a bit of performance data with them. Mostly
I'm concerned about reducing per-interrupt overhead
(due to PIOs), and CPU Utilization, so the following data
shows how these patches change the number of received
packets/interrupt and CPU utilization.
(Let me know if I've missed any relevant patches.)
The data is labelled as follows:
-------------------------------
base : "vanilla" 2.6.12-rc2 kernel
base+mchan1-3 : 2.6.12-rc2 kernel + 3 patches
from mchan [1]
base+mchan1-3+tagged: 2.6.12-rc2 + 3 patches
from mchan [1] + tagged status
patch from davem [2]
base+mchan1-3+coal : 2.6.12-rc2 + 3 patches
from mchan [1] + tg3 interrupt
coalescence patch [3]
[1] http://marc.theaimsgroup.com/?l=linux-netdev&m=111446723510962&w=2
(This is one of a series of 3 patches - the others can't be
found in the archive. But they're all in 2.6.12-rc4.)
[2] http://marc.theaimsgroup.com/?l=linux-netdev&m=111567944730302&w=2
[3] http://marc.theaimsgroup.com/?l=linux-netdev&m=111586526522981&w=2
The system I used was an Altix with 1300MHz CPUs, and
a 5704 Broadcom NIC. The workload was bulk data receive
via TCP, with 1500 a byte MTU.
The following tables summarize the data in the attached
graphs. I had to (grossly) interpolate in some cases,
see the graphs for the real data.
CPU Util[%]
-------------------------------------
base base+ base+ base+
mchan1-3 mchan1-3+ mchan1-3+
Link Util[%] tagged coal
=====================================================
40 36 34 41 27
60 48 45 50 35
80 58 56 58 40
90 59 58 63 42
95 - 57 - 42
Packets/Intr
-------------------------------------
base base+ base+ base+
mchan1-3 mchan1-3+ mchan1-3+
Link Util[%] tagged coal
=====================================================
40 2.2 2.3 1.4 3.4
60 2.7 2.9 1.8 4.1
80 3.0 3.2 2.3 5.2
90 3.1 3.4 2.4 6.2
95 - 3.5 - 6.6
"mchan1-3" gets us up to ~.5 more packets/interrupt,
and adding the "coal" patch ~3.5 more. The "tagged"
patch made things a bit worse, though I haven't pinned
down exactly why that is. Processing more packets per
interrupt results in lower CPU utilization, largely
because we spend less time waiting for PIOs to flush.
--
Arthur
[-- Attachment #2: CPU utilization --]
[-- Type: IMAGE/PNG, Size: 3803 bytes --]
[-- Attachment #3: Received Packets/Interrupt --]
[-- Type: IMAGE/PNG, Size: 3622 bytes --]
^ permalink raw reply
* git repository for net drivers available
From: Jeff Garzik @ 2005-05-13 3:08 UTC (permalink / raw)
To: Netdev; +Cc: Linux Kernel, Andrew Morton
Although I have over 200 net driver patches to go through in my
'Pending' folder, I have fully converted the existing netdev-2.6
repository from BitKeeper to git. This includes the wireless-2.6
repository.
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
The main branch is fairly irrelevant, as you must choose the branch you
wish:
> [jgarzik@pretzel netdev-2.6]$ ls .git/branches/
> 8139cp e1000 ixgb r8169 skge we18
> 8139too-iomap forcedeth janitor register-netdev smc91x wifi
> amd8111 ieee80211 orinoco remove-drivers smc91x-eeprom
> e100 iff-running ppp sis900 starfire
For folks looking for a consolidated netdev-2.6 repository (hi Andrew),
that does not exist yet. I will create an 'ALL' repository for this
purpose, sometime soon.
Jeff
^ permalink raw reply
* Re: ipw2100: intrusive cleanups, working this time ;-)
From: Greg KH @ 2005-05-13 3:42 UTC (permalink / raw)
To: James Ketrenos; +Cc: Pavel Machek, netdev, kernel list, jbohac, jbenc
In-Reply-To: <4283FA4D.3010208@linux.intel.com>
On Thu, May 12, 2005 at 07:52:29PM -0500, James Ketrenos wrote:
>
> Part of the process we have in place is to try and make sure that the
> versions that get picked up by distros and the majority of users have a
> 'known' level of quality. As part of that, we only want to get changes
> pushed to -mm and eventual mainline that have gone through regression
> testing.
Any chance of making those regression tests public so we can all do this
kind of testing on any future changes that might be made to the driver?
Remember, once it hits mainline, lots of different people will be
touching it for various reasons at times...
thanks,
greg k-h
^ permalink raw reply
* [RFC: 2.6 patch] make MII no longer user visible
From: Adrian Bunk @ 2005-05-13 3:52 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linux-kernel
MII is a classical example of a helper option no user should ever see.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
--- linux-2.6.12-rc4-mm1-full/drivers/net/Kconfig.old 2005-05-13 05:47:58.000000000 +0200
+++ linux-2.6.12-rc4-mm1-full/drivers/net/Kconfig 2005-05-13 05:48:27.000000000 +0200
@@ -165,12 +165,8 @@
the questions about Ethernet network cards. If unsure, say N.
config MII
- tristate "Generic Media Independent Interface device support"
+ tristate
depends on NET_ETHERNET
- help
- Most ethernet controllers have MII transceiver either as an external
- or internal device. It is safe to say Y or M here even if your
- ethernet card lack MII.
source "drivers/net/arm/Kconfig"
^ permalink raw reply
* [2.6 patch] document that 8139TOO supports 8129/8130
From: Adrian Bunk @ 2005-05-13 4:04 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linux-kernel
The 8129/8130 support is a sub-option that is not visible if the user
hasn't enabled the 8139 support.
Let's make it a bit easier for users to find the driver for their nic.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
--- linux-2.6.12-rc4-mm1-full/drivers/net/Kconfig.old 2005-05-13 05:54:05.000000000 +0200
+++ linux-2.6.12-rc4-mm1-full/drivers/net/Kconfig 2005-05-13 06:00:21.000000000 +0200
@@ -1484,14 +1484,14 @@
will be called 8139cp. This is recommended.
config 8139TOO
- tristate "RealTek RTL-8139 PCI Fast Ethernet Adapter support"
+ tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
depends on NET_PCI && PCI
select CRC32
select MII
---help---
This is a driver for the Fast Ethernet PCI network cards based on
- the RTL8139 chips. If you have one of those, say Y and read
- the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
+ the RTL 8129/81308139 chips. If you have one of those, say Y and
+ read the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
To compile this driver as a module, choose M here: the module
will be called 8139too. This is recommended.
^ permalink raw reply
* Status of net/ipv4/ipvs/ip_vs_proto_icmp.c?
From: Adrian Bunk @ 2005-05-13 4:16 UTC (permalink / raw)
To: Julian Anastasov, Wensong Zhang; +Cc: netdev, linux-kernel
Hi,
can anyone explain the status of?
This file is always included in the kernel if CONFIG_IP_VS=y, but it's
completely unused.
Will it be made working in the forseeable future or is it a candidate
for removal?
TIA
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
^ permalink raw reply
* Linux Routers working
From: cranium2003 @ 2005-05-13 4:16 UTC (permalink / raw)
To: net dev
Hello,
Is there any way on linux routers to know on
which interface packet is forwarded before actually
packet trasmission begins? Also before packet
processed by IP layer can it be possible to know from
which adjecent Router'IP packet came to that router?
regards,
cranium
__________________________________
Yahoo! Mail Mobile
Take Yahoo! Mail with you! Check email on your mobile phone.
http://mobile.yahoo.com/learn/mail
^ permalink raw reply
* Re: issue with new TCP TSO stuff
From: David S. Miller @ 2005-05-13 4:36 UTC (permalink / raw)
To: herbert; +Cc: netdev
In-Reply-To: <20050512235236.GA22658@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Subject: Re: issue with new TCP TSO stuff
Date: Fri, 13 May 2005 09:52:36 +1000
> > #2 could be handled by down-sizing TSO frames when packet loss occurs.
> > Ie. tcp_retransmit_skb() or whatever will segmentize a TSO packet
> > which is within the sequence it is trying to retransmit. Implementing
> > this is non- trivial mostly due to the fact that it has to work handle
> > GFP_ATOMIC memory failures and also get all the pcount crap correct.
>
> I think most of the code to do that might already be there. Pity
> we'll have to keep track of the pcount though.
Yes, when we walk the queue to retransmit, we chop up the
TSO frame via tcp_trim_head() and tcp_fragment(). It is
very loose and would need refinements though.
I think we'd be OK, because even if we get a GFP_ATOMIC allocation
failure, it's just like any other failure. We're doing retransmits
so a timer will be the worst case deadlock breaker should we get an
allocation failure while chopping up the TSO frame.
This actually makes me worried about sk->sk_send_head advancement.
I think we have a deadlock possible here. If sk->sk_send_head is
the only packet in the output queue, and the remote system has no
reason to send us zero-window probes or any other packets, we could
wedge if the skb_clone() fails for the tcp_transmit_skb() call.
We won't set any timers if we fail to send that single sk->sk_send_head
write queue packet, and we have no pending frames waiting to be ACK'd,
so nothing will wake us up to retry the transmit.
> > and size appropriately. I think the tcp_snd_test() simplifications
> > made by my TSO Reloaded patch would help a lot here. The send test is
> > logically now split to it's two tests 1) whether to send anything at
> > all, and 2) once #1 passes, how many such packets.
>
> That was another one of my comments to your patch :) I was going to
> suggest that we move the cwnd/in_flight loop from tcp_snd_test to
> emit_send_queue.
One elegant part of the tcp_snd_test() in the TCP Reloaded patch is
that tcp_write_queue() calls it exactly once.
That loop in there is bogus and unnecessary. In the changelog for
the TCP Reloaded patch I mention that this can be simplified into:
new_packets = skb_queue_len(&sk->sk_write_queue) - in_flight;
cwnd -= in_flight;
return min(new_packets, cwnd);
It is a BUG() for this calculation to be larger than the number of
packets from sk->sk_send_head to the end of the write queue (which is
the invariant we must guarentee for our caller). We could even check
for this while debugging the implementation early on.
> > This would be a sort of super-TSO that would do less segmenting work
> > than even a "perfect" TSO segmenter would.
> >
> > I'm still not sure which approach is best, just throwing around some
> > ideas.
>
> On paper your new super-TSO approach sounds the best. However, I
> suppose we won't know for sure until we try :)
Yeah, TCP Reloaded sounded really nice on paper too :-)
To handle these super-TSO frames properly, we would need to add
sk->sk_send_offset to go along with sk->sk_send_head. So then
update_send_head() would advance sk->sk_send_offset, and if that
completely consumed sk->sk_send_head then the pointer would be
advanced.
Tests of sk->sk_send_head would need to be fixed up similarly.
^ permalink raw reply
* [PATCH 2.6.12-rc4] ppp_mppe: add PPP MPPE encryption module
From: Matt Domsch @ 2005-05-13 5:41 UTC (permalink / raw)
To: netdev-VZNHf3L845pBDgjK7y7TUQ
Cc: akpm-3NddpPZAyC0,
pptpclient-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
davem-H+wXaHxf7aLQT0dZR+AlfA
The patch below implements the Microsoft Point-to-Point Encryption
method as a PPP compressor/decompressor. This is necessary for Linux
clients and servers to interoperate with Microsoft Point-to-Point
Tunneling Protocol (PPTP) servers (either Microsoft PPTP servers or
the poptop project) which use MPPE to encrypt data when creating a VPN.
This patch differs from the kernel_ppp_mppe DKMS pacakge at
pptpclient.sourceforge.net by utilizing the kernel crypto routines
rather than providing its own SHA1 and arcfour implementations.
Minor changes to ppp_generic.c try to prevent a link from disabling
compression (in our case, the encryption) after it has started using
compression (encryption).
drivers/net/Kconfig | 6
drivers/net/Makefile | 1
drivers/net/ppp_generic.c | 79 +++--
drivers/net/ppp_mppe.c | 724 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/ppp_mppe.h | 87 +++++
include/linux/ppp-comp.h | 14
6 files changed, 888 insertions(+), 23 deletions(-)
Signed-off-by: Matt Domsch <Matt_Domsch-8PEkshWhKlo@public.gmane.org>
Feedback to pptpclient-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org please.
--
Matt Domsch
Software Architect
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com
diff -urNp --exclude-from=/home/mdomsch/excludes --minimal linux-2.6/drivers/net/Kconfig linux-2.6-mppe.git/drivers/net/Kconfig
--- linux-2.6/drivers/net/Kconfig Tue Apr 26 15:14:07 2005
+++ linux-2.6-mppe.git/drivers/net/Kconfig Fri May 13 00:20:04 2005
@@ -2407,6 +2407,16 @@ config PPP_BSDCOMP
module; it is called bsd_comp and will show up in the directory
modules once you have said "make modules". If unsure, say N.
+config PPP_MPPE
+ tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
+ depends on PPP && EXPERIMENTAL
+ ---help---
+ Support for the MPPE Encryption protocol, as employed by the
+ Microsoft Point-to-Point Tunneling Protocol.
+
+ See http://pptpclient.sourceforge.net/ for information on
+ configuring PPTP clients and servers to utilize this method.
+
config PPPOE
tristate "PPP over Ethernet (EXPERIMENTAL)"
depends on EXPERIMENTAL && PPP
diff -urNp --exclude-from=/home/mdomsch/excludes --minimal linux-2.6/drivers/net/Makefile linux-2.6-mppe.git/drivers/net/Makefile
--- linux-2.6/drivers/net/Makefile Tue Apr 26 15:14:07 2005
+++ linux-2.6-mppe.git/drivers/net/Makefile Fri May 13 00:18:01 2005
@@ -104,6 +104,7 @@ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
+obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
obj-$(CONFIG_SLIP) += slip.o
diff -urNp --exclude-from=/home/mdomsch/excludes --minimal linux-2.6/drivers/net/ppp_generic.c linux-2.6-mppe.git/drivers/net/ppp_generic.c
--- linux-2.6/drivers/net/ppp_generic.c Tue Apr 26 15:14:09 2005
+++ linux-2.6-mppe.git/drivers/net/ppp_generic.c Fri May 13 00:18:01 2005
@@ -1027,6 +1027,53 @@ ppp_xmit_process(struct ppp *ppp)
ppp_xmit_unlock(ppp);
}
+static inline struct sk_buff *
+pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
+{
+ struct sk_buff *new_skb;
+ int len;
+ int new_skb_size = ppp->dev->mtu + ppp->xcomp->comp_skb_extra_space + ppp->dev->hard_header_len;
+ int compressor_skb_size = ppp->dev->mtu + ppp->xcomp->comp_skb_extra_space + PPP_HDRLEN;
+ new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
+ if (!new_skb) {
+ if (net_ratelimit())
+ printk(KERN_ERR "PPP: no memory (comp pkt)\n");
+ return NULL;
+ }
+ if (ppp->dev->hard_header_len > PPP_HDRLEN)
+ skb_reserve(new_skb,
+ ppp->dev->hard_header_len - PPP_HDRLEN);
+
+ /* compressor still expects A/C bytes in hdr */
+ len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
+ new_skb->data, skb->len + 2,
+ compressor_skb_size);
+ if (len > 0 && (ppp->flags & SC_CCP_UP)) {
+ kfree_skb(skb);
+ skb = new_skb;
+ skb_put(skb, len);
+ skb_pull(skb, 2); /* pull off A/C bytes */
+ } else if (len == 0) {
+ /* didn't compress, or CCP not up yet */
+ kfree_skb(new_skb);
+ new_skb = skb;
+ } else {
+ /*
+ * (len < 0)
+ * MPPE requires that we do not send unencrypted
+ * frames. The compressor will return -1 if we
+ * should drop the frame. We cannot simply test
+ * the compress_proto because MPPE and MPPC share
+ * the same number.
+ */
+ if (net_ratelimit())
+ printk(KERN_ERR "ppp: compressor dropped pkt\n");
+ kfree_skb(new_skb);
+ new_skb = NULL;
+ }
+ return new_skb;
+}
+
/*
* Compress and send a frame.
* The caller should have locked the xmit path,
@@ -1113,29 +1160,14 @@ ppp_send_frame(struct ppp *ppp, struct s
/* try to do packet compression */
if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
&& proto != PPP_LCP && proto != PPP_CCP) {
- new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
- GFP_ATOMIC);
- if (new_skb == 0) {
- printk(KERN_ERR "PPP: no memory (comp pkt)\n");
+ if (!(ppp->flags & SC_CCP_UP) && ppp->xcomp->must_compress) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n");
goto drop;
}
- if (ppp->dev->hard_header_len > PPP_HDRLEN)
- skb_reserve(new_skb,
- ppp->dev->hard_header_len - PPP_HDRLEN);
-
- /* compressor still expects A/C bytes in hdr */
- len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
- new_skb->data, skb->len + 2,
- ppp->dev->mtu + PPP_HDRLEN);
- if (len > 0 && (ppp->flags & SC_CCP_UP)) {
- kfree_skb(skb);
- skb = new_skb;
- skb_put(skb, len);
- skb_pull(skb, 2); /* pull off A/C bytes */
- } else {
- /* didn't compress, or CCP not up yet */
- kfree_skb(new_skb);
- }
+ skb = pad_compress_skb(ppp, skb);
+ if (!skb)
+ goto drop;
}
/*
@@ -1155,7 +1187,8 @@ ppp_send_frame(struct ppp *ppp, struct s
return;
drop:
- kfree_skb(skb);
+ if (skb)
+ kfree_skb(skb);
++ppp->stats.tx_errors;
}
@@ -1640,7 +1673,7 @@ ppp_decompress_frame(struct ppp *ppp, st
goto err;
if (proto == PPP_COMP) {
- ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN);
+ ns = dev_alloc_skb(ppp->mru + ppp->rcomp->decomp_skb_extra_space + PPP_HDRLEN);
if (ns == 0) {
printk(KERN_ERR "ppp_decompress_frame: no memory\n");
goto err;
diff -urNp --exclude-from=/home/mdomsch/excludes --minimal linux-2.6/drivers/net/ppp_mppe.c linux-2.6-mppe.git/drivers/net/ppp_mppe.c
--- linux-2.6/drivers/net/ppp_mppe.c Wed Dec 31 18:00:00 1969
+++ linux-2.6-mppe.git/drivers/net/ppp_mppe.c Fri May 13 00:18:01 2005
@@ -0,0 +1,724 @@
+/*
+ * ppp_mppe_compress.c - interface MPPE to the PPP code.
+ * This version is for use with Linux kernel 2.2.19+, 2.4.18+ and 2.6.2+.
+ *
+ * By Frank Cusack <frank-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>.
+ * Copyright (c) 2002,2003,2004 Google, Inc.
+ * All rights reserved.
+ *
+ * License:
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, provided that the above copyright
+ * notice appears in all copies. This software is provided without any
+ * warranty, express or implied.
+ *
+ * ALTERNATIVELY, provided that this notice is retained in full, this product
+ * may be distributed under the terms of the GNU General Public License (GPL),
+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Changelog:
+ * 06/18/04 - Matt Domsch <Matt_Domsch-8PEkshWhKlo@public.gmane.org>, Oleg Makarenko <mole-aTJdtAV7WjCHXe+LvDLADg@public.gmane.org>
+ * Use Linux kernel 2.6 arc4 and sha1 routines rather than
+ * providing our own.
+ * 2/15/04 - TS: added #include <version.h> and testing for Kernel
+ * version before using
+ * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
+ * deprecated in 2.6
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/ppp_defs.h>
+#include <linux/ppp-comp.h>
+#include <asm/scatterlist.h>
+
+#include "ppp_mppe.h"
+
+MODULE_AUTHOR("Frank Cusack <frank-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
+MODULE_VERSION("1.0.2");
+
+static void
+setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
+{
+ sg[0].page = virt_to_page(address);
+ sg[0].offset = offset_in_page(address);
+ sg[0].length = length;
+}
+
+#define SHA1_PAD_SIZE 40
+
+/*
+ * kernel crypto API needs its arguments to be in kmalloc'd memory, not in the module
+ * static data area. That means sha_pad needs to be kmalloc'd.
+ */
+
+struct sha_pad {
+ unsigned char sha_pad1[SHA1_PAD_SIZE];
+ unsigned char sha_pad2[SHA1_PAD_SIZE];
+};
+static struct sha_pad *sha_pad;
+
+static inline void sha_pad_init(struct sha_pad *shapad)
+{
+ memset(shapad->sha_pad1, 0x00, sizeof(shapad->sha_pad1));
+ memset(shapad->sha_pad2, 0xF2, sizeof(shapad->sha_pad2));
+}
+
+/*
+ * State for an MPPE (de)compressor.
+ */
+struct ppp_mppe_state {
+ struct crypto_tfm *arc4;
+ struct crypto_tfm *sha1;
+ unsigned char *sha1_digest;
+ unsigned char master_key[MPPE_MAX_KEY_LEN];
+ unsigned char session_key[MPPE_MAX_KEY_LEN];
+ unsigned keylen; /* key length in bytes */
+ /* NB: 128-bit == 16, 40-bit == 8! */
+ /* If we want to support 56-bit, */
+ /* the unit has to change to bits */
+ unsigned char bits; /* MPPE control bits */
+ unsigned ccount; /* 12-bit coherency count (seqno) */
+ unsigned stateful; /* stateful mode flag */
+ int discard; /* stateful mode packet loss flag */
+ int sanity_errors; /* take down LCP if too many */
+ int unit;
+ int debug;
+ struct compstat stats;
+};
+
+/* struct ppp_mppe_state.bits definitions */
+#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */
+#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */
+#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */
+#define MPPE_BIT_D 0x10 /* This is an encrypted frame */
+
+#define MPPE_BIT_FLUSHED MPPE_BIT_A
+#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
+
+#define MPPE_BITS(p) ((p)[4] & 0xf0)
+#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
+#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */
+
+#define MPPE_OVHD 2 /* MPPE overhead/packet */
+#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */
+
+/*
+ * Key Derivation, from RFC 3078, RFC 3079.
+ * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
+ */
+static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
+{
+ struct scatterlist sg[4];
+
+ setup_sg(&sg[0], state->master_key, state->keylen);
+ setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1));
+ setup_sg(&sg[2], state->session_key, state->keylen);
+ setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2));
+
+ crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest);
+
+ memcpy(InterimKey, state->sha1_digest, state->keylen);
+}
+
+/*
+ * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
+ * Well, not what's written there, but rather what they meant.
+ */
+static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
+{
+ unsigned char InterimKey[MPPE_MAX_KEY_LEN];
+ struct scatterlist sg_in[1], sg_out[1];
+
+ get_new_key_from_sha(state, InterimKey);
+ if (!initial_key) {
+ crypto_cipher_setkey(state->arc4, InterimKey, state->keylen);
+ setup_sg(sg_in, InterimKey, state->keylen);
+ setup_sg(sg_out, state->session_key, state->keylen);
+ if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in,
+ state->keylen) != 0) {
+ printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n");
+ }
+ } else {
+ memcpy(state->session_key, InterimKey, state->keylen);
+ }
+ if (state->keylen == 8) {
+ /* See RFC 3078 */
+ state->session_key[0] = 0xd1;
+ state->session_key[1] = 0x26;
+ state->session_key[2] = 0x9e;
+ }
+ crypto_cipher_setkey(state->arc4, state->session_key, state->keylen);
+}
+
+/*
+ * Allocate space for a (de)compressor.
+ */
+static void *mppe_alloc(unsigned char *options, int optlen)
+{
+ struct ppp_mppe_state *state;
+ unsigned int digestsize;
+
+ if (optlen != CILEN_MPPE + sizeof(state->master_key)
+ || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+ goto out;
+
+ state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
+ if (state == NULL)
+ goto out;
+
+ memset(state, 0, sizeof(*state));
+
+ state->arc4 = crypto_alloc_tfm("arc4", 0);
+ if (!state->arc4)
+ goto out_free;
+
+ state->sha1 = crypto_alloc_tfm("sha1", 0);
+ if (!state->sha1)
+ goto out_free;
+
+ digestsize = crypto_tfm_alg_digestsize(state->sha1);
+ if (digestsize < MPPE_MAX_KEY_LEN)
+ goto out_free;
+
+ state->sha1_digest = kmalloc(digestsize, GFP_KERNEL);
+ if (!state->sha1_digest)
+ goto out_free;
+
+ /* Save keys. */
+ memcpy(state->master_key, &options[CILEN_MPPE],
+ sizeof(state->master_key));
+ memcpy(state->session_key, state->master_key,
+ sizeof(state->master_key));
+
+ /*
+ * We defer initial key generation until mppe_init(), as mppe_alloc()
+ * is called frequently during negotiation.
+ */
+
+ return (void *)state;
+
+ out_free:
+ if (state->sha1_digest)
+ kfree(state->sha1_digest);
+ if (state->sha1)
+ crypto_free_tfm(state->sha1);
+ if (state->arc4)
+ crypto_free_tfm(state->arc4);
+ kfree(state);
+ out:
+ return NULL;
+}
+
+/*
+ * Deallocate space for a (de)compressor.
+ */
+static void mppe_free(void *arg)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ if (state) {
+ if (state->sha1_digest)
+ kfree(state->sha1_digest);
+ if (state->sha1)
+ crypto_free_tfm(state->sha1);
+ if (state->arc4)
+ crypto_free_tfm(state->arc4);
+ kfree(state);
+ }
+}
+
+/*
+ * Initialize (de)compressor state.
+ */
+static int
+mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
+ const char *debugstr)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ unsigned char mppe_opts;
+
+ if (optlen != CILEN_MPPE
+ || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+ return 0;
+
+ MPPE_CI_TO_OPTS(&options[2], mppe_opts);
+ if (mppe_opts & MPPE_OPT_128)
+ state->keylen = 16;
+ else if (mppe_opts & MPPE_OPT_40)
+ state->keylen = 8;
+ else {
+ printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr,
+ unit);
+ return 0;
+ }
+ if (mppe_opts & MPPE_OPT_STATEFUL)
+ state->stateful = 1;
+
+ /* Generate the initial session key. */
+ mppe_rekey(state, 1);
+
+ if (debug) {
+ int i;
+ char mkey[sizeof(state->master_key) * 2 + 1];
+ char skey[sizeof(state->session_key) * 2 + 1];
+
+ printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n",
+ debugstr, unit, (state->keylen == 16) ? 128 : 40,
+ (state->stateful) ? "stateful" : "stateless");
+
+ for (i = 0; i < sizeof(state->master_key); i++)
+ sprintf(mkey + i * 2, "%02x", state->master_key[i]);
+ for (i = 0; i < sizeof(state->session_key); i++)
+ sprintf(skey + i * 2, "%02x", state->session_key[i]);
+ printk(KERN_DEBUG
+ "%s[%d]: keys: master: %s initial session: %s\n",
+ debugstr, unit, mkey, skey);
+ }
+
+ /*
+ * Initialize the coherency count. The initial value is not specified
+ * in RFC 3078, but we can make a reasonable assumption that it will
+ * start at 0. Setting it to the max here makes the comp/decomp code
+ * do the right thing (determined through experiment).
+ */
+ state->ccount = MPPE_CCOUNT_SPACE - 1;
+
+ /*
+ * Note that even though we have initialized the key table, we don't
+ * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1.
+ */
+ state->bits = MPPE_BIT_ENCRYPTED;
+
+ state->unit = unit;
+ state->debug = debug;
+
+ return 1;
+}
+
+static int
+mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
+ int hdrlen, int debug)
+{
+ /* ARGSUSED */
+ return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
+}
+
+/*
+ * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
+ * tell the compressor to rekey. Note that we MUST NOT rekey for
+ * every CCP Reset-Request; we only rekey on the next xmit packet.
+ * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
+ * So, rekeying for every CCP Reset-Request is broken as the peer will not
+ * know how many times we've rekeyed. (If we rekey and THEN get another
+ * CCP Reset-Request, we must rekey again.)
+ */
+static void mppe_comp_reset(void *arg)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+ state->bits |= MPPE_BIT_FLUSHED;
+}
+
+/*
+ * Compress (encrypt) a packet.
+ * It's strange to call this a compressor, since the output is always
+ * MPPE_OVHD + 2 bytes larger than the input.
+ */
+static int
+mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
+ int isize, int osize)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ int proto;
+ struct scatterlist sg_in[1], sg_out[1];
+
+ /*
+ * Check that the protocol is in the range we handle.
+ */
+ proto = PPP_PROTOCOL(ibuf);
+ if (proto < 0x0021 || proto > 0x00fa)
+ return 0;
+
+ /* Make sure we have enough room to generate an encrypted packet. */
+ if (osize < isize + MPPE_OVHD + 2) {
+ /* Drop the packet if we should encrypt it, but can't. */
+ printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
+ "(have: %d need: %d)\n", state->unit,
+ osize, osize + MPPE_OVHD + 2);
+ return -1;
+ }
+
+ osize = isize + MPPE_OVHD + 2;
+
+ /*
+ * Copy over the PPP header and set control bits.
+ */
+ obuf[0] = PPP_ADDRESS(ibuf);
+ obuf[1] = PPP_CONTROL(ibuf);
+ obuf[2] = PPP_COMP >> 8; /* isize + MPPE_OVHD + 1 */
+ obuf[3] = PPP_COMP; /* isize + MPPE_OVHD + 2 */
+ obuf += PPP_HDRLEN;
+
+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ if (state->debug >= 7)
+ printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
+ state->ccount);
+ obuf[0] = state->ccount >> 8;
+ obuf[1] = state->ccount & 0xff;
+
+ if (!state->stateful || /* stateless mode */
+ ((state->ccount & 0xff) == 0xff) || /* "flag" packet */
+ (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */
+ /* We must rekey */
+ if (state->debug && state->stateful)
+ printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n",
+ state->unit);
+ mppe_rekey(state, 0);
+ state->bits |= MPPE_BIT_FLUSHED;
+ }
+ obuf[0] |= state->bits;
+ state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */
+
+ obuf += MPPE_OVHD;
+ ibuf += 2; /* skip to proto field */
+ isize -= 2;
+
+ /* Encrypt packet */
+ setup_sg(sg_in, ibuf, isize);
+ setup_sg(sg_out, obuf, osize);
+ if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, isize) != 0) {
+ printk(KERN_DEBUG "crypto_cypher_encrypt failed\n");
+ return -1;
+ }
+
+ state->stats.unc_bytes += isize;
+ state->stats.unc_packets++;
+ state->stats.comp_bytes += osize;
+ state->stats.comp_packets++;
+
+ return osize;
+}
+
+/*
+ * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
+ * to look bad ... and the longer the link is up the worse it will get.
+ */
+static void mppe_comp_stats(void *arg, struct compstat *stats)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+ *stats = state->stats;
+}
+
+static int
+mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
+ int hdrlen, int mru, int debug)
+{
+ /* ARGSUSED */
+ return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
+}
+
+/*
+ * We received a CCP Reset-Ack. Just ignore it.
+ */
+static void mppe_decomp_reset(void *arg)
+{
+ /* ARGSUSED */
+ return;
+}
+
+/*
+ * Decompress (decrypt) an MPPE packet.
+ */
+static int
+mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
+ int osize)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ unsigned ccount;
+ int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
+ int sanity = 0;
+ struct scatterlist sg_in[1], sg_out[1];
+
+ if (isize <= PPP_HDRLEN + MPPE_OVHD) {
+ if (state->debug)
+ printk(KERN_DEBUG
+ "mppe_decompress[%d]: short pkt (%d)\n",
+ state->unit, isize);
+ return DECOMP_ERROR;
+ }
+
+ /*
+ * Make sure we have enough room to decrypt the packet.
+ * Note that for our test we only subtract 1 byte whereas in
+ * mppe_compress() we added 2 bytes (+MPPE_OVHD);
+ * this is to account for possible PFC.
+ */
+ if (osize < isize - MPPE_OVHD - 1) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
+ "(have: %d need: %d)\n", state->unit,
+ osize, isize - MPPE_OVHD - 1);
+ return DECOMP_ERROR;
+ }
+ osize = isize - MPPE_OVHD - 2; /* assume no PFC */
+
+ ccount = MPPE_CCOUNT(ibuf);
+ if (state->debug >= 7)
+ printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n",
+ state->unit, ccount);
+
+ /* sanity checks -- terminate with extreme prejudice */
+ if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
+ printk(KERN_DEBUG
+ "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
+ state->unit);
+ state->sanity_errors += 100;
+ sanity = 1;
+ }
+ if (!state->stateful && !flushed) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
+ "stateless mode!\n", state->unit);
+ state->sanity_errors += 100;
+ sanity = 1;
+ }
+ if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
+ "flag packet!\n", state->unit);
+ state->sanity_errors += 100;
+ sanity = 1;
+ }
+
+ if (sanity) {
+ if (state->sanity_errors < SANITY_MAX)
+ return DECOMP_ERROR;
+ else
+ /*
+ * Take LCP down if the peer is sending too many bogons.
+ * We don't want to do this for a single or just a few
+ * instances since it could just be due to packet corruption.
+ */
+ return DECOMP_FATALERROR;
+ }
+
+ /*
+ * Check the coherency count.
+ */
+
+ if (!state->stateful) {
+ /* RFC 3078, sec 8.1. Rekey for every packet. */
+ while (state->ccount != ccount) {
+ mppe_rekey(state, 0);
+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ }
+ } else {
+ /* RFC 3078, sec 8.2. */
+ if (!state->discard) {
+ /* normal state */
+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ if (ccount != state->ccount) {
+ /*
+ * (ccount > state->ccount)
+ * Packet loss detected, enter the discard state.
+ * Signal the peer to rekey (by sending a CCP Reset-Request).
+ */
+ state->discard = 1;
+ return DECOMP_ERROR;
+ }
+ } else {
+ /* discard state */
+ if (!flushed) {
+ /* ccp.c will be silent (no additional CCP Reset-Requests). */
+ return DECOMP_ERROR;
+ } else {
+ /* Rekey for every missed "flag" packet. */
+ while ((ccount & ~0xff) !=
+ (state->ccount & ~0xff)) {
+ mppe_rekey(state, 0);
+ state->ccount =
+ (state->ccount +
+ 256) % MPPE_CCOUNT_SPACE;
+ }
+
+ /* reset */
+ state->discard = 0;
+ state->ccount = ccount;
+ /*
+ * Another problem with RFC 3078 here. It implies that the
+ * peer need not send a Reset-Ack packet. But RFC 1962
+ * requires it. Hopefully, M$ does send a Reset-Ack; even
+ * though it isn't required for MPPE synchronization, it is
+ * required to reset CCP state.
+ */
+ }
+ }
+ if (flushed)
+ mppe_rekey(state, 0);
+ }
+
+ /*
+ * Fill in the first part of the PPP header. The protocol field
+ * comes from the decrypted data.
+ */
+ obuf[0] = PPP_ADDRESS(ibuf); /* +1 */
+ obuf[1] = PPP_CONTROL(ibuf); /* +1 */
+ obuf += 2;
+ ibuf += PPP_HDRLEN + MPPE_OVHD;
+ isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */
+ /* net osize: isize-4 */
+
+ /*
+ * Decrypt the first byte in order to check if it is
+ * a compressed or uncompressed protocol field.
+ */
+ setup_sg(sg_in, ibuf, 1);
+ setup_sg(sg_out, obuf, 1);
+ if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, 1) != 0) {
+ printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
+ return DECOMP_ERROR;
+ }
+
+ /*
+ * Do PFC decompression.
+ * This would be nicer if we were given the actual sk_buff
+ * instead of a char *.
+ */
+ if ((obuf[0] & 0x01) != 0) {
+ obuf[1] = obuf[0];
+ obuf[0] = 0;
+ obuf++;
+ osize++;
+ }
+
+ /* And finally, decrypt the rest of the packet. */
+ setup_sg(sg_in, ibuf + 1, isize - 1);
+ setup_sg(sg_out, obuf + 1, osize - 1);
+ if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, isize - 1) != 0) {
+ printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
+ return DECOMP_ERROR;
+ }
+
+ state->stats.unc_bytes += osize;
+ state->stats.unc_packets++;
+ state->stats.comp_bytes += isize;
+ state->stats.comp_packets++;
+
+ /* good packet credit */
+ state->sanity_errors >>= 1;
+
+ return osize;
+}
+
+/*
+ * Incompressible data has arrived (this should never happen!).
+ * We should probably drop the link if the protocol is in the range
+ * of what should be encrypted. At the least, we should drop this
+ * packet. (How to do this?)
+ */
+static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+ if (state->debug &&
+ (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
+ printk(KERN_DEBUG
+ "mppe_incomp[%d]: incompressible (unencrypted) data! "
+ "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
+
+ state->stats.inc_bytes += icnt;
+ state->stats.inc_packets++;
+ state->stats.unc_bytes += icnt;
+ state->stats.unc_packets++;
+}
+
+/*************************************************************
+ * Module interface table
+ *************************************************************/
+
+/*
+ * Procedures exported to if_ppp.c.
+ */
+static struct compressor ppp_mppe = {
+ .compress_proto = CI_MPPE,
+ .comp_alloc = mppe_alloc,
+ .comp_free = mppe_free,
+ .comp_init = mppe_comp_init,
+ .comp_reset = mppe_comp_reset,
+ .compress = mppe_compress,
+ .comp_stat = mppe_comp_stats,
+ .decomp_alloc = mppe_alloc,
+ .decomp_free = mppe_free,
+ .decomp_init = mppe_decomp_init,
+ .decomp_reset = mppe_decomp_reset,
+ .decompress = mppe_decompress,
+ .incomp = mppe_incomp,
+ .decomp_stat = mppe_comp_stats,
+ .owner = THIS_MODULE,
+ .comp_skb_extra_space = MPPE_COMPRESS_PAD,
+ .decomp_skb_extra_space = MPPE_DECOMPRESS_PAD,
+ .must_compress = 1,
+};
+
+/*
+ * ppp_mppe_init()
+ *
+ * Prior to allowing load, try to load the arc4 and sha1 crypto
+ * libraries. The actual use will be allocated later, but
+ * this way the module will fail to insmod if they aren't available.
+ */
+
+static int __init ppp_mppe_init(void)
+{
+ int answer;
+ if (!(crypto_alg_available("arc4", 0) &&
+ crypto_alg_available("sha1", 0)))
+ return -ENODEV;
+
+ sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);
+ if (!sha_pad)
+ return -ENOMEM;
+ sha_pad_init(sha_pad);
+
+ answer = ppp_register_compressor(&ppp_mppe);
+
+ if (answer == 0)
+ printk(KERN_INFO "PPP MPPE Compression module registered\n");
+ else
+ kfree(sha_pad);
+
+ return answer;
+}
+
+static void __exit ppp_mppe_cleanup(void)
+{
+ ppp_unregister_compressor(&ppp_mppe);
+ kfree(sha_pad);
+}
+
+module_init(ppp_mppe_init);
+module_exit(ppp_mppe_cleanup);
diff -urNp --exclude-from=/home/mdomsch/excludes --minimal linux-2.6/drivers/net/ppp_mppe.h linux-2.6-mppe.git/drivers/net/ppp_mppe.h
--- linux-2.6/drivers/net/ppp_mppe.h Wed Dec 31 18:00:00 1969
+++ linux-2.6-mppe.git/drivers/net/ppp_mppe.h Fri May 13 00:18:01 2005
@@ -0,0 +1,87 @@
+#define MPPE_COMPRESS_PAD 8 /* MPPE growth per frame */
+#define MPPE_DECOMPRESS_PAD 128
+#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */
+
+/* option bits for ccp_options.mppe */
+#define MPPE_OPT_40 0x01 /* 40 bit */
+#define MPPE_OPT_128 0x02 /* 128 bit */
+#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */
+/* unsupported opts */
+#define MPPE_OPT_56 0x08 /* 56 bit */
+#define MPPE_OPT_MPPC 0x10 /* MPPC compression */
+#define MPPE_OPT_D 0x20 /* Unknown */
+#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
+#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */
+
+/*
+ * This is not nice ... the alternative is a bitfield struct though.
+ * And unfortunately, we cannot share the same bits for the option
+ * names above since C and H are the same bit. We could do a u_int32
+ * but then we have to do a htonl() all the time and/or we still need
+ * to know which octet is which.
+ */
+#define MPPE_C_BIT 0x01 /* MPPC */
+#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */
+#define MPPE_L_BIT 0x20 /* 40-bit */
+#define MPPE_S_BIT 0x40 /* 128-bit */
+#define MPPE_M_BIT 0x80 /* 56-bit, not supported */
+#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */
+
+/* Does not include H bit; used for least significant octet only. */
+#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
+
+/* Build a CI from mppe opts (see RFC 3078) */
+#define MPPE_OPTS_TO_CI(opts, ci) \
+ do { \
+ u_char *ptr = ci; /* u_char[4] */ \
+ \
+ /* H bit */ \
+ if (opts & MPPE_OPT_STATEFUL) \
+ *ptr++ = 0x0; \
+ else \
+ *ptr++ = MPPE_H_BIT; \
+ *ptr++ = 0; \
+ *ptr++ = 0; \
+ \
+ /* S,L bits */ \
+ *ptr = 0; \
+ if (opts & MPPE_OPT_128) \
+ *ptr |= MPPE_S_BIT; \
+ if (opts & MPPE_OPT_40) \
+ *ptr |= MPPE_L_BIT; \
+ /* M,D,C bits not supported */ \
+ } while (/* CONSTCOND */ 0)
+
+/* The reverse of the above */
+#define MPPE_CI_TO_OPTS(ci, opts) \
+ do { \
+ u_char *ptr = ci; /* u_char[4] */ \
+ \
+ opts = 0; \
+ \
+ /* H bit */ \
+ if (!(ptr[0] & MPPE_H_BIT)) \
+ opts |= MPPE_OPT_STATEFUL; \
+ \
+ /* S,L bits */ \
+ if (ptr[3] & MPPE_S_BIT) \
+ opts |= MPPE_OPT_128; \
+ if (ptr[3] & MPPE_L_BIT) \
+ opts |= MPPE_OPT_40; \
+ \
+ /* M,D,C bits */ \
+ if (ptr[3] & MPPE_M_BIT) \
+ opts |= MPPE_OPT_56; \
+ if (ptr[3] & MPPE_D_BIT) \
+ opts |= MPPE_OPT_D; \
+ if (ptr[3] & MPPE_C_BIT) \
+ opts |= MPPE_OPT_MPPC; \
+ \
+ /* Other bits */ \
+ if (ptr[0] & ~MPPE_H_BIT) \
+ opts |= MPPE_OPT_UNKNOWN; \
+ if (ptr[1] || ptr[2]) \
+ opts |= MPPE_OPT_UNKNOWN; \
+ if (ptr[3] & ~MPPE_ALL_BITS) \
+ opts |= MPPE_OPT_UNKNOWN; \
+ } while (/* CONSTCOND */ 0)
diff -urNp --exclude-from=/home/mdomsch/excludes --minimal linux-2.6/include/linux/ppp-comp.h linux-2.6-mppe.git/include/linux/ppp-comp.h
--- linux-2.6/include/linux/ppp-comp.h Tue Apr 26 15:15:06 2005
+++ linux-2.6-mppe.git/include/linux/ppp-comp.h Fri May 13 00:18:01 2005
@@ -111,6 +111,13 @@ struct compressor {
/* Used in locking compressor modules */
struct module *owner;
+ /* Extra skb space needed by the compressor algorithm */
+ unsigned int comp_skb_extra_space;
+ /* Extra skb space needed by the decompressor algorithm */
+ unsigned int decomp_skb_extra_space;
+ /* if must_compress is set, but ppp->flags != SC_CCP_UP
+ * then drop the packet */
+ unsigned int must_compress;
};
/*
@@ -189,6 +196,13 @@ struct compressor {
#define DEFLATE_METHOD(x) ((x) & 0x0F)
#define DEFLATE_MAKE_OPT(w) ((((w) - 8) << 4) + DEFLATE_METHOD_VAL)
#define DEFLATE_CHK_SEQUENCE 0
+
+/*
+ * Definitions for MPPE.
+ */
+
+#define CI_MPPE 18 /* config option for MPPE */
+#define CILEN_MPPE 6 /* length of config option */
/*
* Definitions for other, as yet unsupported, compression methods.
-------------------------------------------------------
This SF.Net email is sponsored by Oracle Space Sweepstakes
Want to be the first software developer in space?
Enter now for the Oracle Space Sweepstakes!
http://ads.osdn.com/?ad_id=7393&alloc_id=16281&op=click
^ permalink raw reply
* Re: ipw2100: intrusive cleanups, working this time ;-)
From: James Ketrenos @ 2005-05-13 6:25 UTC (permalink / raw)
To: Greg KH; +Cc: Pavel Machek, netdev, kernel list, jbohac, jbenc
In-Reply-To: <20050513034201.GA11817@kroah.com>
Greg KH wrote:
>On Thu, May 12, 2005 at 07:52:29PM -0500, James Ketrenos wrote:
>
>
>>Part of the process we have in place is to try and make sure that the
>>versions that get picked up by distros and the majority of users have a
>>'known' level of quality. As part of that, we only want to get changes
>>pushed to -mm and eventual mainline that have gone through regression
>>testing.
>>
>>
>
>Any chance of making those regression tests public so we can all do this
>kind of testing on any future changes that might be made to the driver?
>
>
I believe all of our test plans are available publically. We just put
up test runner on our bugzilla server so that we can better track which
tests have been run by users, etc. Some tests are automated, some are
manual.
The bugzilla site is http://bughost.org and test tracker is toward the
bottom of that page.
You can also find information at http://ipw2200.sf.net/validation.php
>Remember, once it hits mainline, lots of different people will be
>touching it for various reasons at times...
>
>
I am hopeful that if we can get a process streamlined enough so that
regression passes can occur quickly, we will be able to keep pace w/ any
critical fixes or changes that are desired to go into mainline.
What is driving the approach is that our customers want to build
solutions with drivers that have gone through a known level of
interoperability and functionality testing.
We ideally want to be able to say "you can either download the driver
version X from http://whatever, or any mainline kernel newer than
2.6.13+". However we can only do that if the code that is pulled into
mainline /has/ gone through all of that testing.
The reality of the community process may require that we can only say
"version X from http://whatever or versions 2.6.{x,y,z} of the kernel"
if patches are accepted into the tree that haven't been sufficiently tested.
We want to have a process that meets the needs of the end users, the
ipw* and kernel development communities, the platform manufacturers, and
the distros.
James
>thanks,
>
>greg k-h
>
>
^ permalink raw reply
* Re: ipw2100: intrusive cleanups, working this time ;-)
From: Christoph Hellwig @ 2005-05-13 8:21 UTC (permalink / raw)
To: James Ketrenos; +Cc: Pavel Machek, netdev, kernel list, jbohac, jbenc
In-Reply-To: <4283FA4D.3010208@linux.intel.com>
On Thu, May 12, 2005 at 07:52:29PM -0500, James Ketrenos wrote:
> Part of the process we have in place is to try and make sure that the
> versions that get picked up by distros and the majority of users have a
> 'known' level of quality. As part of that, we only want to get changes
> pushed to -mm and eventual mainline that have gone through regression
> testing.
The only wait to make that works is to opensource the testsuites and allow
the distros to run the QA test themselves. Except for maybe SuSE no one
will pick up a driver version just because you say so.
p.s. please remove the part of the mail you follow up to that's not relevant
yo your posting. thanks.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox