From: Dan Williams <dcbw@redhat.com>
To: Luis Carlos Cobo <luisca@cozybit.com>
Cc: linux-wireless@vger.kernel.org
Subject: Re: [PATCH 5/7] o80211s: (zd1211rw-mac80211) support for mesh interface
Date: Wed, 31 Oct 2007 08:02:07 -0400 [thread overview]
Message-ID: <1193832127.23775.26.camel@localhost.localdomain> (raw)
In-Reply-To: <4727de15.0abd720a.7b07.ffffb1f7@mx.google.com>
On Mon, 2007-10-29 at 18:15 -0700, Luis Carlos Cobo wrote:
> Signed-off-by: Luis Carlos Cobo <luisca@cozybit.com>
> ---
> drivers/net/wireless/zd1211rw-mac80211/zd_chip.c | 1 +
> drivers/net/wireless/zd1211rw-mac80211/zd_chip.h | 8 +++
> drivers/net/wireless/zd1211rw-mac80211/zd_mac.c | 72 +++++++++++++++++++++-
> drivers/net/wireless/zd1211rw-mac80211/zd_mac.h | 3 +
> drivers/net/wireless/zd1211rw-mac80211/zd_usb.c | 11 +++-
> 5 files changed, 92 insertions(+), 3 deletions(-)
Hi Luis!
Awesome to see this work. I assume you're developing on zd1211 then?
Would similar changes be necessary to support other devices?
> diff --git a/drivers/net/wireless/zd1211rw-mac80211/zd_chip.c b/drivers/net/wireless/zd1211rw-mac80211/zd_chip.c
> index a220420..fb6d27b 100644
> --- a/drivers/net/wireless/zd1211rw-mac80211/zd_chip.c
> +++ b/drivers/net/wireless/zd1211rw-mac80211/zd_chip.c
> @@ -806,6 +806,7 @@ static int hw_init_hmac(struct zd_chip *chip)
> { CR_AFTER_PNP, 0x1 },
> { CR_WEP_PROTECT, 0x114 },
> { CR_IFS_VALUE, IFS_VALUE_DEFAULT },
> + { CR_CAM_MODE, MODE_AP_WDS},
> };
>
> ZD_ASSERT(mutex_is_locked(&chip->mutex));
> diff --git a/drivers/net/wireless/zd1211rw-mac80211/zd_chip.h b/drivers/net/wireless/zd1211rw-mac80211/zd_chip.h
> index a88a569..46900be 100644
> --- a/drivers/net/wireless/zd1211rw-mac80211/zd_chip.h
> +++ b/drivers/net/wireless/zd1211rw-mac80211/zd_chip.h
> @@ -486,6 +486,7 @@ enum {
>
> #define CR_RX_OFFSET CTL_REG(0x065c)
>
> +#define CR_BCN_LENGTH CTL_REG(0x0664)
> #define CR_PHY_DELAY CTL_REG(0x066C)
> #define CR_BCN_FIFO CTL_REG(0x0670)
> #define CR_SNIFFER_ON CTL_REG(0x0674)
> @@ -542,6 +543,8 @@ enum {
> #define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \
> RX_FILTER_CFEND | RX_FILTER_CFACK)
>
> +#define BCN_MODE_IBSS 0x2000000
> +
> /* Monitor mode sets filter to 0xfffff */
>
> #define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690)
> @@ -575,6 +578,11 @@ enum {
>
> /* CAM: Continuous Access Mode (power management) */
> #define CR_CAM_MODE CTL_REG(0x0700)
> +#define MODE_IBSS 0x0
> +#define MODE_AP 0x1
> +#define MODE_STA 0x2
> +#define MODE_AP_WDS 0x3
> +
> #define CR_CAM_ROLL_TB_LOW CTL_REG(0x0704)
> #define CR_CAM_ROLL_TB_HIGH CTL_REG(0x0708)
> #define CR_CAM_ADDRESS CTL_REG(0x070C)
> diff --git a/drivers/net/wireless/zd1211rw-mac80211/zd_mac.c b/drivers/net/wireless/zd1211rw-mac80211/zd_mac.c
> index ad6a8d5..b668abd 100644
> --- a/drivers/net/wireless/zd1211rw-mac80211/zd_mac.c
> +++ b/drivers/net/wireless/zd1211rw-mac80211/zd_mac.c
> @@ -493,6 +493,45 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
> /* FIXME: Management frame? */
> }
>
> +void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
> +{
> + struct zd_mac *mac = zd_hw_mac(hw);
> + u32 tmp, j = 0;
> + /* 4 more bytes for tail CRC */
> + u32 full_len = beacon->len + 4;
> + zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0);
> + zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
> + /* 0x2 (BIT_1) in vendor driver, maybe they meant 0x1? */
> + while (tmp & 0x2) {
There should be a break out here to avoid an infinite loop. Maybe add
'|| (j > 1000)' or something like that.
> + zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
> + if ((++j % 100) == 0)
> + printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n");
> + msleep(1);
> + }
> +
> + zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1 );
> + if (zd_chip_is_zd1211b(&mac->chip)) {
> + zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1);
> + }
> +
> + for (j=0 ; j < beacon->len; j++) {
> + zd_iowrite32(&mac->chip, CR_BCN_FIFO,s
> + * ((u8 *)(beacon->data + j)));
> + }
> +
> + for (j=0; j< 4; j++) {
> + zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0);
> + }
> +
> + zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
> + /* 802.11b/g 2.4G CCK 1Mb
> + * 802.11a, not yet implemented, uses different values (see GPL vendor
> + * driver)
> + */
> + zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 |
> + (full_len << 19));
> +}
> +
> static int fill_ctrlset(struct zd_mac *mac,
> struct sk_buff *skb,
> struct ieee80211_tx_control *control)
> @@ -701,6 +740,7 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
>
> switch (conf->type) {
> case IEEE80211_IF_TYPE_MNTR:
> + case IEEE80211_IF_TYPE_MESH:
> case IEEE80211_IF_TYPE_STA:
> mac->type = conf->type;
> break;
> @@ -729,15 +769,44 @@ static int zd_op_config_interface(struct ieee80211_hw *hw, int if_id,
> struct ieee80211_if_conf *conf)
> {
> struct zd_mac *mac = zd_hw_mac(hw);
> + int associated;
> +
> + if (mac->type == IEEE80211_IF_TYPE_MESH) {
> + associated = true ;
> + if (hw->flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE) {
> + zd_mac_config_beacon(hw, conf->beacon);
> + kfree_skb(conf->beacon);
> + zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | 100);
> + }
> + }
> + else
The } and else should be on the same line.
> + associated = is_valid_ether_addr(conf->bssid);
>
> spin_lock_irq(&mac->lock);
> - mac->associated = is_valid_ether_addr(conf->bssid);
> + mac->associated = associated;
> spin_unlock_irq(&mac->lock);
>
> /* TODO: do hardware bssid filtering */
> return 0;
> }
>
> +void zd_process_intr(struct work_struct *work)
> +{
> + u16 int_status;
> + struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
> +
> + int_status = le16_to_cpu(*(u16*)(mac->intr_buffer+4));
> + if (int_status & INT_CFG_NEXT_BCN) {
> + dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
> + }
> + else {
Same here.
Cheers,
Dan
> + dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
> + }
> +
> + zd_chip_enable_hwint(&mac->chip);
> +}
> +
> +
> static void set_multicast_hash_handler(struct work_struct *work)
> {
> struct zd_mac *mac =
> @@ -929,6 +998,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
> INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
> INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
> INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler);
> + INIT_WORK(&mac->process_intr, zd_process_intr);
>
> SET_IEEE80211_DEV(hw, &intf->dev);
> return hw;
> diff --git a/drivers/net/wireless/zd1211rw-mac80211/zd_mac.h b/drivers/net/wireless/zd1211rw-mac80211/zd_mac.h
> index ed5417c..fbfc2e8 100644
> --- a/drivers/net/wireless/zd1211rw-mac80211/zd_mac.h
> +++ b/drivers/net/wireless/zd1211rw-mac80211/zd_mac.h
> @@ -169,12 +169,15 @@ struct zd_tx_skb_control_block {
> struct zd_mac {
> struct zd_chip chip;
> spinlock_t lock;
> + spinlock_t intr_lock;
> struct ieee80211_hw *hw;
> struct housekeeping housekeeping;
> struct work_struct set_multicast_hash_work;
> struct work_struct set_rts_cts_work;
> struct work_struct set_rx_filter_work;
> + struct work_struct process_intr;
> struct zd_mc_hash multicast_hash;
> + u8 intr_buffer[USB_MAX_EP_INT_BUFFER];
> u8 regdomain;
> u8 default_regdomain;
> int type;
> diff --git a/drivers/net/wireless/zd1211rw-mac80211/zd_usb.c b/drivers/net/wireless/zd1211rw-mac80211/zd_usb.c
> index 15ea70e..972a370 100644
> --- a/drivers/net/wireless/zd1211rw-mac80211/zd_usb.c
> +++ b/drivers/net/wireless/zd1211rw-mac80211/zd_usb.c
> @@ -92,6 +92,7 @@ MODULE_DEVICE_TABLE(usb, usb_ids);
> #define FW_ZD1211B_PREFIX "zd1211/zd1211b_"
>
> /* USB device initialization */
> +static void int_urb_complete(struct urb *urb);
>
> static int request_fw_file(
> const struct firmware **fw, const char *name, struct device *device)
> @@ -331,11 +332,18 @@ static inline void handle_regs_int(struct urb *urb)
> struct zd_usb *usb = urb->context;
> struct zd_usb_interrupt *intr = &usb->intr;
> int len;
> + u16 int_num;
>
> ZD_ASSERT(in_interrupt());
> spin_lock(&intr->lock);
>
> - if (intr->read_regs_enabled) {
> + int_num = le16_to_cpu(*(u16*)(urb->transfer_buffer+2));
> + if( int_num == CR_INTERRUPT ){
> + struct zd_mac *mac = zd_hw_mac(zd_usb_to_hw(urb->context));
> + memcpy(&mac->intr_buffer, urb->transfer_buffer,
> + USB_MAX_EP_INT_BUFFER);
> + schedule_work(&mac->process_intr);
> + } else if (intr->read_regs_enabled) {
> intr->read_regs.length = len = urb->actual_length;
>
> if (len > sizeof(intr->read_regs.buffer))
> @@ -346,7 +354,6 @@ static inline void handle_regs_int(struct urb *urb)
> goto out;
> }
>
> - dev_dbg_f(urb_dev(urb), "regs interrupt ignored\n");
> out:
> spin_unlock(&intr->lock);
> }
next prev parent reply other threads:[~2007-10-31 12:03 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-30 1:15 [PATCH 5/7] o80211s: (zd1211rw-mac80211) support for mesh interface Luis Carlos Cobo
2007-10-31 12:02 ` Dan Williams [this message]
2007-10-31 19:06 ` Luis Carlos Cobo
2007-10-31 12:17 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1193832127.23775.26.camel@localhost.localdomain \
--to=dcbw@redhat.com \
--cc=linux-wireless@vger.kernel.org \
--cc=luisca@cozybit.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox