Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 90110
b: refs/heads/master
c: 72e77a8
h: refs/heads/master
v: v3
  • Loading branch information
Luis Carlos Cobo authored and John W. Linville committed Mar 6, 2008
1 parent af1d3a0 commit c06db80
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f137e05468f2a648aba11377dc824d788683dff4
refs/heads/master: 72e77a8a7921d952bdef2468d9315616eca6b464
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/zd1211rw/zd_chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,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));
Expand Down
8 changes: 8 additions & 0 deletions trunk/drivers/net/wireless/zd1211rw/zd_chip.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,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)
Expand Down Expand Up @@ -545,6 +546,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)
Expand Down Expand Up @@ -578,6 +581,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)
Expand Down
75 changes: 73 additions & 2 deletions trunk/drivers/net/wireless/zd1211rw/zd_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,46 @@ 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);
while (tmp & 0x2) {
zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
if ((++j % 100) == 0) {
printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n");
if (j >= 500) {
printk(KERN_ERR "Giving up beacon config.\n");
return;
}
}
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,
*((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)
Expand Down Expand Up @@ -709,6 +749,7 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,

switch (conf->type) {
case IEEE80211_IF_TYPE_MNTR:
case IEEE80211_IF_TYPE_MESH_POINT:
case IEEE80211_IF_TYPE_STA:
mac->type = conf->type;
break;
Expand Down Expand Up @@ -738,15 +779,43 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
struct ieee80211_if_conf *conf)
{
struct zd_mac *mac = zd_hw_mac(hw);
int associated;

if (mac->type == IEEE80211_IF_TYPE_MESH_POINT) {
associated = true;
if (conf->beacon) {
zd_mac_config_beacon(hw, conf->beacon);
kfree_skb(conf->beacon);
zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
hw->conf.beacon_int);
}
} else
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) {
if (net_ratelimit())
dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
} else
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 =
Expand Down Expand Up @@ -912,7 +981,8 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)

hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;

hw->flags = IEEE80211_HW_RX_INCLUDES_FCS;
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
hw->max_rssi = 100;
hw->max_signal = 100;

Expand All @@ -926,6 +996,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;
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/wireless/zd1211rw/zd_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,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;
Expand Down
11 changes: 9 additions & 2 deletions trunk/drivers/net/wireless/zd1211rw/zd_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,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)
Expand Down Expand Up @@ -336,11 +337,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))
Expand All @@ -351,7 +359,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);
}
Expand Down

0 comments on commit c06db80

Please sign in to comment.