o wl3501: use the MIB stuff in this card, add one more wireless extension

. Using the MIB in the card I'm now able to find lots of useful information
  that will get used in more support for wireless extensions.
. Also some cleanups wrt ifdefing the code not yet used to write into the
  flash of this card and some more messages tidy up.
parent 02c3473c
......@@ -62,6 +62,103 @@ enum wl3501_signals {
WL3501_SIG_MM_IND,
};
enum wl3501_mib_attribs {
WL3501_MIB_ATTR_STATION_ID,
WL3501_MIB_ATTR_AUTH_ALGORITHMS,
WL3501_MIB_ATTR_AUTH_TYPE,
WL3501_MIB_ATTR_MEDIUM_OCCUPANCY_LIMIT,
WL3501_MIB_ATTR_CF_POLLABLE,
WL3501_MIB_ATTR_CFP_PERIOD,
WL3501_MIB_ATTR_CFPMAX_DURATION,
WL3501_MIB_ATTR_AUTH_RESP_TMOUT,
WL3501_MIB_ATTR_RX_DTIMS,
WL3501_MIB_ATTR_PRIV_OPT_IMPLEMENTED,
WL3501_MIB_ATTR_PRIV_INVOKED,
WL3501_MIB_ATTR_WEP_DEFAULT_KEYS,
WL3501_MIB_ATTR_WEP_DEFAULT_KEY_ID,
WL3501_MIB_ATTR_WEP_KEY_MAPPINGS,
WL3501_MIB_ATTR_WEP_KEY_MAPPING_LENGTH,
WL3501_MIB_ATTR_EXCLUDE_UNENCRYPTED,
WL3501_MIB_ATTR_WEP_ICV_ERROR_COUNT,
WL3501_MIB_ATTR_WEP_UNDECRYPTABLE_COUNT,
WL3501_MIB_ATTR_WEP_EXCLUDED_COUNT,
WL3501_MIB_ATTR_MAC_ADDR,
WL3501_MIB_ATTR_GROUP_ADDRS,
WL3501_MIB_ATTR_RTS_THRESHOLD,
WL3501_MIB_ATTR_SHORT_RETRY_LIMIT,
WL3501_MIB_ATTR_LONG_RETRY_LIMIT,
WL3501_MIB_ATTR_FRAG_THRESHOLD,
WL3501_MIB_ATTR_MAX_TX_MSDU_LIFETIME,
WL3501_MIB_ATTR_MAX_RX_LIFETIME,
WL3501_MIB_ATTR_MANUFACTURER_ID,
WL3501_MIB_ATTR_PRODUCT_ID,
WL3501_MIB_ATTR_TRANSMITTED_FRAG_COUNT,
WL3501_MIB_ATTR_MULTICAST_TRANSMITTED_FRAME_COUNT,
WL3501_MIB_ATTR_FAILED_COUNT,
WL3501_MIB_ATTR_RX_FRAG_COUNT,
WL3501_MIB_ATTR_MULTICAST_RX_COUNT,
WL3501_MIB_ATTR_FCS_ERROR_COUNT,
WL3501_MIB_ATTR_RETRY_COUNT,
WL3501_MIB_ATTR_MULTIPLE_RETRY_COUNT,
WL3501_MIB_ATTR_RTS_SUCCESS_COUNT,
WL3501_MIB_ATTR_RTS_FAILURE_COUNT,
WL3501_MIB_ATTR_ACK_FAILURE_COUNT,
WL3501_MIB_ATTR_FRAME_DUPLICATE_COUNT,
WL3501_MIB_ATTR_PHY_TYPE,
WL3501_MIB_ATTR_REG_DOMAINS_SUPPORT,
WL3501_MIB_ATTR_CURRENT_REG_DOMAIN,
WL3501_MIB_ATTR_SLOT_TIME,
WL3501_MIB_ATTR_CCA_TIME,
WL3501_MIB_ATTR_RX_TX_TURNAROUND_TIME,
WL3501_MIB_ATTR_TX_PLCP_DELAY,
WL3501_MIB_ATTR_RX_TX_SWITCH_TIME,
WL3501_MIB_ATTR_TX_RAMP_ON_TIME,
WL3501_MIB_ATTR_TX_RF_DELAY,
WL3501_MIB_ATTR_SIFS_TIME,
WL3501_MIB_ATTR_RX_RF_DELAY,
WL3501_MIB_ATTR_RX_PLCP_DELAY,
WL3501_MIB_ATTR_MAC_PROCESSING_DELAY,
WL3501_MIB_ATTR_TX_RAMP_OFF_TIME,
WL3501_MIB_ATTR_PREAMBLE_LENGTH,
WL3501_MIB_ATTR_PLCP_HEADER_LENGTH,
WL3501_MIB_ATTR_MPDU_DURATION_FACTOR,
WL3501_MIB_ATTR_AIR_PROPAGATION_TIME,
WL3501_MIB_ATTR_TEMP_TYPE,
WL3501_MIB_ATTR_CW_MIN,
WL3501_MIB_ATTR_CW_MAX,
WL3501_MIB_ATTR_SUPPORT_DATA_RATES_TX,
WL3501_MIB_ATTR_SUPPORT_DATA_RATES_RX,
WL3501_MIB_ATTR_MPDU_MAX_LENGTH,
WL3501_MIB_ATTR_SUPPORT_TX_ANTENNAS,
WL3501_MIB_ATTR_CURRENT_TX_ANTENNA,
WL3501_MIB_ATTR_SUPPORT_RX_ANTENNAS,
WL3501_MIB_ATTR_DIVERSITY_SUPPORT,
WL3501_MIB_ATTR_DIVERSITY_SELECTION_RS,
WL3501_MIB_ATTR_NR_SUPPORTED_PWR_LEVELS,
WL3501_MIB_ATTR_TX_PWR_LEVEL1,
WL3501_MIB_ATTR_TX_PWR_LEVEL2,
WL3501_MIB_ATTR_TX_PWR_LEVEL3,
WL3501_MIB_ATTR_TX_PWR_LEVEL4,
WL3501_MIB_ATTR_TX_PWR_LEVEL5,
WL3501_MIB_ATTR_TX_PWR_LEVEL6,
WL3501_MIB_ATTR_TX_PWR_LEVEL7,
WL3501_MIB_ATTR_TX_PWR_LEVEL8,
WL3501_MIB_ATTR_CURRENT_TX_PWR_LEVEL,
WL3501_MIB_ATTR_CURRENT_CHAN,
WL3501_MIB_ATTR_CCA_MODE_SUPPORTED,
WL3501_MIB_ATTR_CURRENT_CCA_MODE,
WL3501_MIB_ATTR_ED_THRESHOLD,
WL3501_MIB_ATTR_SINTHESIZER_LOCKED,
WL3501_MIB_ATTR_CURRENT_PWR_STATE,
WL3501_MIB_ATTR_DOZE_TURNON_TIME,
WL3501_MIB_ATTR_RCR33,
WL3501_MIB_ATTR_DEFAULT_CHAN,
WL3501_MIB_ATTR_SSID,
WL3501_MIB_ATTR_PWR_MGMT_ENABLE,
WL3501_MIB_ATTR_NET_CAPABILITY,
WL3501_MIB_ATTR_ROUTING,
};
enum wl3501_net_type {
WL3501_NET_TYPE_INFRA,
WL3501_NET_TYPE_ADHOC,
......@@ -197,6 +294,13 @@ struct wl3501_auth_confirm {
unsigned char mac_addr[ETH_ALEN];
};
struct wl3501_get_req {
u16 next_blk;
unsigned char sig_id;
unsigned char reserved;
u16 mib_attrib;
};
struct wl3501_get_confirm {
u16 next_blk;
unsigned char sig_id;
......@@ -412,6 +516,8 @@ struct wl3501_card {
int base_addr;
struct wl3501_mac_addr mac_addr;
spinlock_t lock;
wait_queue_head_t wait;
struct wl3501_get_confirm sig_get_confirm;
u16 tx_buffer_size;
u16 tx_buffer_head;
u16 tx_buffer_tail;
......
......@@ -79,13 +79,6 @@ MODULE_PARM(pc_debug, "i");
#define dprintk(n, format, args...)
#endif
static u8 wl3501_fpage[] = {
[0] = WL3501_BSS_FPAGE0,
[1] = WL3501_BSS_FPAGE1,
[2] = WL3501_BSS_FPAGE2,
[3] = WL3501_BSS_FPAGE3,
};
/*
* Conversion from Channel (this->chan) to frequency, this information
* was obtained from the Planet WAP 1000 Access Point web interface. -acme
......@@ -151,34 +144,6 @@ static __inline__ void wl3501_switch_page(struct wl3501_card *this, u8 page)
wl3501_outb(page, this->base_addr + WL3501_NIC_BSS);
}
/*
* Hold SUTRO. (i.e. make SUTRO stop)
* Return: 1 if SUTRO is originally running
*/
static int wl3501_hold_sutro(struct wl3501_card *this)
{
u8 old = inb(this->base_addr + WL3501_NIC_GCR);
u8 new = (old & ~(WL3501_GCR_ECINT | WL3501_GCR_INT2EC)) |
WL3501_GCR_ECWAIT;
wl3501_outb(new, this->base_addr + WL3501_NIC_GCR);
return !(old & WL3501_GCR_ECWAIT);
}
/*
* UnHold SUTRO. (i.e. make SUTRO running)
* Return: 1 if SUTRO is originally running
*/
static int wl3501_unhold_sutro(struct wl3501_card *this)
{
u8 old = inb(this->base_addr + WL3501_NIC_GCR);
u8 new = old & (~(WL3501_GCR_ECINT | WL3501_GCR_INT2EC |
WL3501_GCR_ECWAIT));
wl3501_outb(new, this->base_addr + WL3501_NIC_GCR);
return !(old & WL3501_GCR_ECWAIT);
}
/*
* Get Ethernet MAC addresss.
*
......@@ -224,6 +189,43 @@ static int wl3501_get_flash_mac_addr(struct wl3501_card *this)
return this->mac_addr.b0 == 0x00 && this->mac_addr.b1 == 0x60;
}
#if 0
static u8 wl3501_fpage[] = {
[0] = WL3501_BSS_FPAGE0,
[1] = WL3501_BSS_FPAGE1,
[2] = WL3501_BSS_FPAGE2,
[3] = WL3501_BSS_FPAGE3,
};
/*
* Hold SUTRO. (i.e. make SUTRO stop)
* Return: 1 if SUTRO is originally running
*/
static int wl3501_hold_sutro(struct wl3501_card *this)
{
u8 old = inb(this->base_addr + WL3501_NIC_GCR);
u8 new = (old & ~(WL3501_GCR_ECINT | WL3501_GCR_INT2EC)) |
WL3501_GCR_ECWAIT;
wl3501_outb(new, this->base_addr + WL3501_NIC_GCR);
return !(old & WL3501_GCR_ECWAIT);
}
/*
* UnHold SUTRO. (i.e. make SUTRO running)
* Return: 1 if SUTRO is originally running
*/
static int wl3501_unhold_sutro(struct wl3501_card *this)
{
u8 old = inb(this->base_addr + WL3501_NIC_GCR);
u8 new = old & (~(WL3501_GCR_ECINT | WL3501_GCR_INT2EC |
WL3501_GCR_ECWAIT));
wl3501_outb(new, this->base_addr + WL3501_NIC_GCR);
return !(old & WL3501_GCR_ECWAIT);
}
static void wl3501_flash_outb(struct wl3501_card *this, u16 page, u16 addr,
u8 data)
{
......@@ -407,6 +409,7 @@ static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf,
out:
return rc;
}
#endif
/**
* wl3501_set_to_wla - Move 'size' bytes from PC to card
......@@ -421,8 +424,6 @@ void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, int size)
/* switch to SRAM Page 0 */
wl3501_switch_page(this, (dest & 0x8000) ? WL3501_BSS_SPAGE1 :
WL3501_BSS_SPAGE0);
/* wl3501_outb(((dest>> 11) & 0x18), this->base_addr +
WL3501_NIC_BSS); */
/* set LMAL and LMAH */
wl3501_outb(dest & 0xff, this->base_addr + WL3501_NIC_LMAL);
wl3501_outb(((dest >> 8) & 0x7f), this->base_addr + WL3501_NIC_LMAH);
......@@ -527,7 +528,7 @@ static int wl3501_esbq_req_test(struct wl3501_card *this)
return tmp & 0x80;
}
static void wl3501_esbq_req(struct wl3501_card *this, u16 * ptr)
static void wl3501_esbq_req(struct wl3501_card *this, u16 *ptr)
{
u16 tmp = 0;
......@@ -538,6 +539,32 @@ static void wl3501_esbq_req(struct wl3501_card *this, u16 * ptr)
this->esbq_req_head = this->esbq_req_start;
}
static int wl3501_get_mib_value(struct wl3501_card *this, u8 index,
void *bf, int size)
{
struct wl3501_get_req signal;
int rc = -EIO;
signal.next_blk = 0;
signal.sig_id = WL3501_SIG_GET_REQ;
signal.mib_attrib = index;
if (wl3501_esbq_req_test(this)) {
u16 ptr = wl3501_get_tx_buffer(this, sizeof(signal));
if (ptr) {
wl3501_set_to_wla(this, ptr, &signal, sizeof(signal));
wl3501_esbq_req(this, &ptr);
this->sig_get_confirm.mib_status = 255;
rc = wait_event_interruptible(this->wait,
this->sig_get_confirm.mib_status != 255);
if (!rc)
memcpy(bf, this->sig_get_confirm.mib_value,
size);
}
}
return rc;
}
/**
* wl3501_send_pkt - Send a packet.
* @this - card
......@@ -1013,8 +1040,8 @@ static void wl3501_online(struct net_device *dev)
{
struct wl3501_card *this = (struct wl3501_card *)dev->priv;
printk(KERN_INFO "Wireless LAN online. BSSID: "
"%02X %02X %02X %02X %02X %02X\n",
printk(KERN_INFO "%s: Wireless LAN online. BSSID: "
"%02X %02X %02X %02X %02X %02X\n", dev->name,
this->bssid.b0, this->bssid.b1, this->bssid.b2,
this->bssid.b3, this->bssid.b4, this->bssid.b5);
netif_wake_queue(dev);
......@@ -1209,20 +1236,10 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this,
u16 addr)
{
struct wl3501_get_confirm sig;
dprintk(3, "entry");
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
#if 0
if (!sig.mib_status) {
switch (sig.mib_attrib) {
case wl3501_mib_mac_addr:
break;
case wl3501_mib_current_reg_domain:
break;
}
}
#endif
wl3501_get_from_wla(this, addr, &this->sig_get_confirm,
sizeof(this->sig_get_confirm));
wake_up(&this->wait);
}
static inline void wl3501_start_confirm_interrupt(struct net_device *dev,
......@@ -1412,13 +1429,10 @@ static int wl3501_init_firmware(struct wl3501_card *this)
wl3501_get_from_wla(this, 0x1a00,
this->card_name, sizeof(this->card_name));
this->card_name[sizeof(this->card_name) - 1] = '\0';
printk(KERN_INFO "%s: card_name=%s\n", __FUNCTION__, this->card_name);
this->firmware_date[0] = '\0';
wl3501_get_from_wla(this, 0x1a40,
this->firmware_date, sizeof(this->firmware_date));
this->firmware_date[sizeof(this->firmware_date) - 1] = '\0';
printk(KERN_INFO "%s: firmware_date=%s\n", __FUNCTION__,
this->firmware_date);
/* Switch to SRAM Page 0 */
wl3501_switch_page(this, WL3501_BSS_SPAGE0);
/* Read parameter from card */
......@@ -1501,12 +1515,8 @@ static int wl3501_reset(struct net_device *dev)
struct wl3501_card *this = (struct wl3501_card *)dev->priv;
int rc = -ENODEV;
/* Stop processing interrupt from the card */
wl3501_block_interrupt(this);
/* Initial WL3501 firmware */
printk(KERN_INFO "%s: Initialize WL3501 firmware...\n", dev->name);
if (wl3501_init_firmware(this)) {
printk(KERN_WARNING "%s: Can't initialize Firmware!\n",
dev->name);
......@@ -1515,15 +1525,15 @@ static int wl3501_reset(struct net_device *dev)
goto out;
}
/* queue has to be started only when the Card is Started */
/*
* Queue has to be started only when the Card is Started
*/
netif_stop_queue(dev);
this->adhoc_times = 0;
wl3501_ack_interrupt(this);
/* Enable interrupt from card */
wl3501_unblock_interrupt(this);
wl3501_mgmt_scan(this, 100);
printk(KERN_INFO "%s: device reset\n", dev->name);
dprintk(1, "%s: device reset", dev->name);
rc = 0;
out:
return rc;
......@@ -1599,7 +1609,7 @@ static int wl3501_open(struct net_device *dev)
link->open++;
/* Initial WL3501 firmware */
printk(KERN_INFO "%s: Initialize WL3501 firmware...\n", dev->name);
dprintk(1, "%s: Initialize WL3501 firmware...", dev->name);
if (wl3501_init_firmware(this))
goto fail;
/* Initial device variables */
......@@ -1611,7 +1621,11 @@ static int wl3501_open(struct net_device *dev)
wl3501_unblock_interrupt(this);
wl3501_mgmt_scan(this, 100);
rc = 0;
printk(KERN_INFO "%s: WL3501 opened\n", dev->name);
dprintk(1, "%s: WL3501 opened", dev->name);
printk(KERN_INFO "%s: Card Name: %s\n"
"%s: Firmware Date: %s\n",
dev->name, this->card_name,
dev->name, this->firmware_date);
out:
spin_unlock_irqrestore(&this->lock, flags);
return rc;
......@@ -2058,25 +2072,42 @@ static int wl3501_get_rate(struct net_device *dev, struct iw_request_info *info,
return 0;
}
static int wl3501_get_rts_threshold(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
u16 threshold;
struct wl3501_card *this = (struct wl3501_card *)dev->priv;
int rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_RTS_THRESHOLD,
&threshold, sizeof(threshold));
if (!rc) {
wrqu->rts.value = threshold;
wrqu->rts.disabled = threshold >= 2347;
wrqu->rts.fixed = 1;
}
return rc;
}
static const iw_handler wl3501_handler[] = {
[SIOCGIWNAME - SIOCSIWCOMMIT] = wl3501_get_name,
[SIOCSIWFREQ - SIOCSIWCOMMIT] = wl3501_set_freq,
[SIOCGIWFREQ - SIOCSIWCOMMIT] = wl3501_get_freq,
[SIOCSIWMODE - SIOCSIWCOMMIT] = wl3501_set_mode,
[SIOCGIWMODE - SIOCSIWCOMMIT] = wl3501_get_mode,
[SIOCGIWSENS - SIOCSIWCOMMIT] = wl3501_get_sens,
[SIOCGIWRANGE - SIOCSIWCOMMIT] = wl3501_get_range,
[SIOCSIWSPY - SIOCSIWCOMMIT] = iw_handler_set_spy,
[SIOCGIWSPY - SIOCSIWCOMMIT] = iw_handler_get_spy,
[SIOCSIWTHRSPY - SIOCSIWCOMMIT] = iw_handler_set_thrspy,
[SIOCGIWTHRSPY - SIOCSIWCOMMIT] = iw_handler_get_thrspy,
[SIOCSIWAP - SIOCSIWCOMMIT] = wl3501_set_wap,
[SIOCGIWAP - SIOCSIWCOMMIT] = wl3501_get_wap,
[SIOCSIWESSID - SIOCSIWCOMMIT] = wl3501_set_essid,
[SIOCGIWESSID - SIOCSIWCOMMIT] = wl3501_get_essid,
[SIOCSIWNICKN - SIOCSIWCOMMIT] = wl3501_set_nick,
[SIOCGIWNICKN - SIOCSIWCOMMIT] = wl3501_get_nick,
[SIOCGIWRATE - SIOCSIWCOMMIT] = wl3501_get_rate,
[SIOCGIWNAME - SIOCIWFIRST] = wl3501_get_name,
[SIOCSIWFREQ - SIOCIWFIRST] = wl3501_set_freq,
[SIOCGIWFREQ - SIOCIWFIRST] = wl3501_get_freq,
[SIOCSIWMODE - SIOCIWFIRST] = wl3501_set_mode,
[SIOCGIWMODE - SIOCIWFIRST] = wl3501_get_mode,
[SIOCGIWSENS - SIOCIWFIRST] = wl3501_get_sens,
[SIOCGIWRANGE - SIOCIWFIRST] = wl3501_get_range,
[SIOCSIWSPY - SIOCIWFIRST] = iw_handler_set_spy,
[SIOCGIWSPY - SIOCIWFIRST] = iw_handler_get_spy,
[SIOCSIWTHRSPY - SIOCIWFIRST] = iw_handler_set_thrspy,
[SIOCGIWTHRSPY - SIOCIWFIRST] = iw_handler_get_thrspy,
[SIOCSIWAP - SIOCIWFIRST] = wl3501_set_wap,
[SIOCGIWAP - SIOCIWFIRST] = wl3501_get_wap,
[SIOCSIWESSID - SIOCIWFIRST] = wl3501_set_essid,
[SIOCGIWESSID - SIOCIWFIRST] = wl3501_get_essid,
[SIOCSIWNICKN - SIOCIWFIRST] = wl3501_set_nick,
[SIOCGIWNICKN - SIOCIWFIRST] = wl3501_get_nick,
[SIOCGIWRATE - SIOCIWFIRST] = wl3501_get_rate,
[SIOCGIWRTS - SIOCIWFIRST] = wl3501_get_rts_threshold,
};
static const struct iw_handler_def wl3501_handler_def = {
......@@ -2293,6 +2324,7 @@ static void wl3501_config(dev_link_t *link)
this->rssi = 255;
strlcpy(this->nick, "Planet WL3501", sizeof(this->nick));
spin_lock_init(&this->lock);
init_waitqueue_head(&this->wait);
switch (this->freq_domain) {
case 0x31:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment