Broken out the vdcf's code into another patch, as it caused problems in the last RFC.
Larry? Can you please give these changes another go and check if the "code refactoring"
or the new memory managment caused the funny crashes?
---
diff -Nurp a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
--- a/drivers/net/wireless/p54/p54common.c 2008-09-29 20:41:44.000000000 +0200
+++ b/drivers/net/wireless/p54/p54common.c 2008-10-05 01:46:00.000000000 +0200
@@ -1064,53 +1064,43 @@ do { \
queue.txop = cpu_to_le16(_txop); \
} while(0)
-static void p54_init_vdcf(struct ieee80211_hw *dev)
+static int p54_set_vdcf(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
struct p54_control_hdr *hdr;
struct p54_tx_control_vdcf *vdcf;
+ hdr = kzalloc(sizeof(struct p54_tx_control_vdcf) + priv->tx_hdr_len +
+ sizeof(struct p54_control_hdr), GFP_ATOMIC);
+ if (!hdr)
+ return -ENOMEM;
+
/* all USB V1 adapters need a extra headroom */
- hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
+ hdr = (void *)hdr + priv->tx_hdr_len;
hdr->magic1 = cpu_to_le16(0x8001);
hdr->len = cpu_to_le16(sizeof(*vdcf));
hdr->type = cpu_to_le16(P54_CONTROL_TYPE_DCFINIT);
- hdr->req_id = cpu_to_le32(priv->rx_start);
-
- vdcf = (struct p54_tx_control_vdcf *) hdr->data;
-
- P54_SET_QUEUE(vdcf->queue[0], 0x0002, 0x0003, 0x0007, 47);
- P54_SET_QUEUE(vdcf->queue[1], 0x0002, 0x0007, 0x000f, 94);
- P54_SET_QUEUE(vdcf->queue[2], 0x0003, 0x000f, 0x03ff, 0);
- P54_SET_QUEUE(vdcf->queue[3], 0x0007, 0x000f, 0x03ff, 0);
-}
-
-static void p54_set_vdcf(struct ieee80211_hw *dev)
-{
- struct p54_common *priv = dev->priv;
- struct p54_control_hdr *hdr;
- struct p54_tx_control_vdcf *vdcf;
-
- hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
-
- p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf));
+ hdr->retry1 = hdr->retry2 = 0;
vdcf = (struct p54_tx_control_vdcf *) hdr->data;
-
+ vdcf->round_trip_delay = cpu_to_le16(0);
+ memset(vdcf->mapping, 0, sizeof(vdcf->mapping));
+ memcpy(vdcf->queue, priv->qos_params, sizeof(vdcf->queue));
if (dev->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
vdcf->slottime = 9;
- vdcf->magic1 = 0x10;
- vdcf->magic2 = 0x00;
+ vdcf->sifs = 0x10;
+ vdcf->eofpad = 0x00;
} else {
vdcf->slottime = 20;
- vdcf->magic1 = 0x0a;
- vdcf->magic2 = 0x06;
+ vdcf->sifs = 0x0a;
+ vdcf->eofpad = 0x06;
}
-
/* (see prism54/isl_oid.h for further details) */
vdcf->frameburst = cpu_to_le16(0);
- priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*vdcf), 0);
+ p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf));
+ priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*vdcf), 1);
+ return 0;
}
static int p54_start(struct ieee80211_hw *dev)
@@ -1118,34 +1108,27 @@ static int p54_start(struct ieee80211_hw
struct p54_common *priv = dev->priv;
int err;
- if (!priv->cached_vdcf) {
- priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf)+
- priv->tx_hdr_len + sizeof(struct p54_control_hdr),
- GFP_KERNEL);
-
- if (!priv->cached_vdcf)
- return -ENOMEM;
- }
-
if (!priv->cached_stats) {
priv->cached_stats = kzalloc(sizeof(struct p54_statistics) +
priv->tx_hdr_len + sizeof(struct p54_control_hdr),
GFP_KERNEL);
- if (!priv->cached_stats) {
- kfree(priv->cached_vdcf);
- priv->cached_vdcf = NULL;
+ if (!priv->cached_stats)
return -ENOMEM;
- }
}
err = priv->open(dev);
if (!err)
priv->mode = NL80211_IFTYPE_MONITOR;
- p54_init_vdcf(dev);
+ P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47);
+ P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94);
+ P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
+ P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
+ err = p54_set_vdcf(dev);
+ if (!err)
+ mod_timer(&priv->stats_timer, jiffies + HZ);
- mod_timer(&priv->stats_timer, jiffies + HZ);
return err;
}
@@ -1215,7 +1198,8 @@ static int p54_config(struct ieee80211_h
2 : conf->antenna_sel_tx - 1;
priv->output_power = conf->power_level << 2;
ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
- p54_set_vdcf(dev);
+ if (!ret)
+ ret = p54_set_vdcf(dev);
mutex_unlock(&priv->conf_mutex);
return ret;
}
@@ -1270,20 +1254,14 @@ static int p54_conf_tx(struct ieee80211_
const struct ieee80211_tx_queue_params *params)
{
struct p54_common *priv = dev->priv;
- struct p54_tx_control_vdcf *vdcf;
-
- vdcf = (struct p54_tx_control_vdcf *)(((struct p54_control_hdr *)
- ((void *)priv->cached_vdcf + priv->tx_hdr_len))->data);
if ((params) && !(queue > 4)) {
- P54_SET_QUEUE(vdcf->queue[queue], params->aifs,
+ P54_SET_QUEUE(priv->qos_params[queue], params->aifs,
params->cw_min, params->cw_max, params->txop);
} else
return -EINVAL;
- p54_set_vdcf(dev);
-
- return 0;
+ return p54_set_vdcf(dev);
}
static int p54_init_xbow_synth(struct ieee80211_hw *dev)
@@ -1422,7 +1400,6 @@ void p54_free_common(struct ieee80211_hw
kfree(priv->iq_autocal);
kfree(priv->output_limit);
kfree(priv->curve_data);
- kfree(priv->cached_vdcf);
}
EXPORT_SYMBOL_GPL(p54_free_common);
diff -Nurp a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
--- a/drivers/net/wireless/p54/p54common.h 2008-09-29 20:39:31.000000000 +0200
+++ b/drivers/net/wireless/p54/p54common.h 2008-10-02 17:30:57.000000000 +0200
@@ -7,8 +7,12 @@
* Copyright (c) 2006, Michael Wu <[email protected]>
* Copyright (c) 2007, Christian Lamparter <[email protected]>
*
- * Based on the islsm (softmac prism54) driver, which is:
- * Copyright 2004-2006 Jean-Baptiste Note <[email protected]>, et al.
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ * Copyright 2004-2006 Jean-Baptiste Note <[email protected]>, et al.
+ *
+ * - LMAC API interface header file for STLC4560 (lmac_longbow.h)
+ * Copyright (C) 2007 Conexant Systems, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -285,21 +289,15 @@ struct p54_tx_control_led {
__le16 duration;
} __attribute__ ((packed));
-struct p54_tx_vdcf_queues {
- __le16 aifs;
- __le16 cwmin;
- __le16 cwmax;
- __le16 txop;
-} __attribute__ ((packed));
-
struct p54_tx_control_vdcf {
- u8 padding;
+ u8 flags;
u8 slottime;
- u8 magic1;
- u8 magic2;
+ u8 sifs;
+ u8 eofpad;
struct p54_tx_vdcf_queues queue[8];
- u8 pad2[4];
+ u8 mapping[4];
__le16 frameburst;
+ __le16 round_trip_delay;
} __attribute__ ((packed));
struct p54_statistics {
diff -Nurp a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
--- a/drivers/net/wireless/p54/p54.h 2008-09-29 20:39:31.000000000 +0200
+++ b/drivers/net/wireless/p54/p54.h 2008-10-02 17:57:41.000000000 +0200
@@ -49,6 +49,14 @@ struct p54_control_hdr {
u8 data[0];
} __attribute__ ((packed));
+struct p54_tx_vdcf_queues {
+ u8 aifs;
+ u8 padding;
+ __le16 cwmin;
+ __le16 cwmax;
+ __le16 txop;
+} __attribute__ ((packed));
+
#define EEPROM_READBACK_LEN 0x3fc
#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
@@ -85,13 +93,13 @@ struct p54_common {
u8 version;
u8 rx_antenna;
unsigned int tx_hdr_len;
- void *cached_vdcf;
unsigned int fw_var;
unsigned int fw_interface;
unsigned int output_power;
u32 tsf_low32;
u32 tsf_high32;
struct ieee80211_tx_queue_stats tx_stats[8];
+ struct p54_tx_vdcf_queues qos_params[8];
struct ieee80211_low_level_stats stats;
struct timer_list stats_timer;
struct completion stats_comp;
On Thursday 09 October 2008 17:20:25 Larry Finger wrote:
> Christian Lamparter wrote:
> > Broken out the vdcf's code into another patch, as it caused problems in the last RFC.
>
> This patch has the following insertion as a replacement:
>
> +struct p54_tx_vdcf_queues {
> + u8 aifs;
> + u8 padding;
> + __le16 cwmin;
> + __le16 cwmax;
> + __le16 txop;
> +} __attribute__ ((packed));
Well, I took this idea from stlc45xx. But now, after some digging in the specs about WMM...
I came to the conclusion that this is superfluous. I'll revert back to the original __le16 aifs,
in the next RFC/RFT round... But now, we should better fix the code for big-endian machines.
I tried to use qemu to emulate a PPC machine, but it's painfully slow and the QEMU's USB
loop through code doesn't work as advertised (yet?).
Regards,
Chr
Christian Lamparter wrote:
> Broken out the vdcf's code into another patch, as it caused problems in the last RFC.
This patch has the following insertion as a replacement:
+struct p54_tx_vdcf_queues {
+ u8 aifs;
+ u8 padding;
+ __le16 cwmin;
+ __le16 cwmax;
+ __le16 txop;
+} __attribute__ ((packed));
Previously, aifs was of type __le16. With this change, the macro
P54_SET_QUEUE must be changed as follows:
#define P54_SET_QUEUE(queue, ai_fs, cw_min, cw_max, _txop) \
do { \
- queue.aifs = cpu_to_le16(ai_fs); \
+ queue.aifs = ai_fs; \
queue.cwmin = cpu_to_le16(cw_min); \
queue.cwmax = cpu_to_le16(cw_max); \
queue.txop = cpu_to_le16(_txop); \
To further emphasize that the second parameter is u8, I also suggest
the following changes in the macro invocation:
- P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47);
- P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94);
- P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
- P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
+ P54_SET_QUEUE(priv->qos_params[0], 0x02, 0x0003, 0x0007, 47);
+ P54_SET_QUEUE(priv->qos_params[1], 0x02, 0x0007, 0x000f, 94);
+ P54_SET_QUEUE(priv->qos_params[2], 0x03, 0x000f, 0x03ff, 0);
+ P54_SET_QUEUE(priv->qos_params[3], 0x07, 0x000f, 0x03ff, 0);
Larry