0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <linux/delay.h>
0032 #include <linux/types.h>
0033 #include <linux/interrupt.h>
0034 #include <linux/in.h>
0035 #include <linux/kernel.h>
0036 #include <linux/module.h>
0037 #include <linux/fcntl.h>
0038 #include <linux/if_arp.h>
0039 #include <linux/ioport.h>
0040 #include <linux/netdevice.h>
0041 #include <linux/etherdevice.h>
0042 #include <linux/skbuff.h>
0043 #include <linux/slab.h>
0044 #include <linux/string.h>
0045 #include <linux/wireless.h>
0046 #include <net/cfg80211.h>
0047
0048 #include <net/iw_handler.h>
0049
0050 #include <pcmcia/cistpl.h>
0051 #include <pcmcia/cisreg.h>
0052 #include <pcmcia/ds.h>
0053
0054 #include <asm/io.h>
0055 #include <linux/uaccess.h>
0056
0057 #include "wl3501.h"
0058
0059 #ifndef __i386__
0060 #define slow_down_io()
0061 #endif
0062
0063
0064 #define WL3501_NOPLOOP(n) { int x = 0; while (x++ < n) slow_down_io(); }
0065
0066
0067
0068 #define wl3501_outb(a, b) { outb(a, b); slow_down_io(); }
0069 #define wl3501_outb_p(a, b) { outb_p(a, b); slow_down_io(); }
0070 #define wl3501_outsb(a, b, c) { outsb(a, b, c); slow_down_io(); }
0071
0072 #define WL3501_RELEASE_TIMEOUT (25 * HZ)
0073 #define WL3501_MAX_ADHOC_TRIES 16
0074
0075 #define WL3501_RESUME 0
0076 #define WL3501_SUSPEND 1
0077
0078 static int wl3501_config(struct pcmcia_device *link);
0079 static void wl3501_release(struct pcmcia_device *link);
0080
0081 static const struct {
0082 int reg_domain;
0083 int min, max, deflt;
0084 } iw_channel_table[] = {
0085 {
0086 .reg_domain = IW_REG_DOMAIN_FCC,
0087 .min = 1,
0088 .max = 11,
0089 .deflt = 1,
0090 },
0091 {
0092 .reg_domain = IW_REG_DOMAIN_DOC,
0093 .min = 1,
0094 .max = 11,
0095 .deflt = 1,
0096 },
0097 {
0098 .reg_domain = IW_REG_DOMAIN_ETSI,
0099 .min = 1,
0100 .max = 13,
0101 .deflt = 1,
0102 },
0103 {
0104 .reg_domain = IW_REG_DOMAIN_SPAIN,
0105 .min = 10,
0106 .max = 11,
0107 .deflt = 10,
0108 },
0109 {
0110 .reg_domain = IW_REG_DOMAIN_FRANCE,
0111 .min = 10,
0112 .max = 13,
0113 .deflt = 10,
0114 },
0115 {
0116 .reg_domain = IW_REG_DOMAIN_MKK,
0117 .min = 14,
0118 .max = 14,
0119 .deflt = 14,
0120 },
0121 {
0122 .reg_domain = IW_REG_DOMAIN_MKK1,
0123 .min = 1,
0124 .max = 14,
0125 .deflt = 1,
0126 },
0127 {
0128 .reg_domain = IW_REG_DOMAIN_ISRAEL,
0129 .min = 3,
0130 .max = 9,
0131 .deflt = 9,
0132 },
0133 };
0134
0135
0136
0137
0138
0139
0140
0141
0142 static int iw_valid_channel(int reg_domain, int channel)
0143 {
0144 int i, rc = 0;
0145
0146 for (i = 0; i < ARRAY_SIZE(iw_channel_table); i++)
0147 if (reg_domain == iw_channel_table[i].reg_domain) {
0148 rc = channel >= iw_channel_table[i].min &&
0149 channel <= iw_channel_table[i].max;
0150 break;
0151 }
0152 return rc;
0153 }
0154
0155
0156
0157
0158
0159
0160
0161 static int iw_default_channel(int reg_domain)
0162 {
0163 int i, rc = 1;
0164
0165 for (i = 0; i < ARRAY_SIZE(iw_channel_table); i++)
0166 if (reg_domain == iw_channel_table[i].reg_domain) {
0167 rc = iw_channel_table[i].deflt;
0168 break;
0169 }
0170 return rc;
0171 }
0172
0173 static void iw_set_mgmt_info_element(enum iw_mgmt_info_element_ids id,
0174 struct iw_mgmt_info_element *el,
0175 void *value, int len)
0176 {
0177 el->id = id;
0178 el->len = len;
0179 memcpy(el->data, value, len);
0180 }
0181
0182 static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to,
0183 struct iw_mgmt_info_element *from)
0184 {
0185 iw_set_mgmt_info_element(from->id, to, from->data, from->len);
0186 }
0187
0188 static inline void wl3501_switch_page(struct wl3501_card *this, u8 page)
0189 {
0190 wl3501_outb(page, this->base_addr + WL3501_NIC_BSS);
0191 }
0192
0193
0194
0195
0196
0197
0198
0199 static int wl3501_get_flash_mac_addr(struct wl3501_card *this)
0200 {
0201 int base_addr = this->base_addr;
0202
0203
0204 wl3501_outb(WL3501_BSS_FPAGE3, base_addr + WL3501_NIC_BSS);
0205 wl3501_outb(0x00, base_addr + WL3501_NIC_LMAL);
0206 wl3501_outb(0x40, base_addr + WL3501_NIC_LMAH);
0207
0208
0209 WL3501_NOPLOOP(100);
0210 this->mac_addr[0] = inb(base_addr + WL3501_NIC_IODPA);
0211 WL3501_NOPLOOP(100);
0212 this->mac_addr[1] = inb(base_addr + WL3501_NIC_IODPA);
0213 WL3501_NOPLOOP(100);
0214 this->mac_addr[2] = inb(base_addr + WL3501_NIC_IODPA);
0215 WL3501_NOPLOOP(100);
0216 this->mac_addr[3] = inb(base_addr + WL3501_NIC_IODPA);
0217 WL3501_NOPLOOP(100);
0218 this->mac_addr[4] = inb(base_addr + WL3501_NIC_IODPA);
0219 WL3501_NOPLOOP(100);
0220 this->mac_addr[5] = inb(base_addr + WL3501_NIC_IODPA);
0221 WL3501_NOPLOOP(100);
0222 this->reg_domain = inb(base_addr + WL3501_NIC_IODPA);
0223 WL3501_NOPLOOP(100);
0224 wl3501_outb(WL3501_BSS_FPAGE0, base_addr + WL3501_NIC_BSS);
0225 wl3501_outb(0x04, base_addr + WL3501_NIC_LMAL);
0226 wl3501_outb(0x40, base_addr + WL3501_NIC_LMAH);
0227 WL3501_NOPLOOP(100);
0228 this->version[0] = inb(base_addr + WL3501_NIC_IODPA);
0229 WL3501_NOPLOOP(100);
0230 this->version[1] = inb(base_addr + WL3501_NIC_IODPA);
0231
0232 wl3501_switch_page(this, WL3501_BSS_SPAGE0);
0233
0234
0235 return this->mac_addr[0] == 0x00 && this->mac_addr[1] == 0x60;
0236 }
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 static void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src,
0248 int size)
0249 {
0250
0251 wl3501_switch_page(this, (dest & 0x8000) ? WL3501_BSS_SPAGE1 :
0252 WL3501_BSS_SPAGE0);
0253
0254 wl3501_outb(dest & 0xff, this->base_addr + WL3501_NIC_LMAL);
0255 wl3501_outb(((dest >> 8) & 0x7f), this->base_addr + WL3501_NIC_LMAH);
0256
0257
0258 wl3501_outsb(this->base_addr + WL3501_NIC_IODPA, src, size);
0259 }
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 static void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest,
0271 int size)
0272 {
0273
0274 wl3501_switch_page(this, (src & 0x8000) ? WL3501_BSS_SPAGE1 :
0275 WL3501_BSS_SPAGE0);
0276
0277 wl3501_outb(src & 0xff, this->base_addr + WL3501_NIC_LMAL);
0278 wl3501_outb((src >> 8) & 0x7f, this->base_addr + WL3501_NIC_LMAH);
0279
0280
0281 insb(this->base_addr + WL3501_NIC_IODPA, dest, size);
0282 }
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296 static u16 wl3501_get_tx_buffer(struct wl3501_card *this, u16 len)
0297 {
0298 u16 next, blk_cnt = 0, zero = 0;
0299 u16 full_len = sizeof(struct wl3501_80211_tx_hdr) + len;
0300 u16 ret = 0;
0301
0302 if (full_len > this->tx_buffer_cnt * 254)
0303 goto out;
0304 ret = this->tx_buffer_head;
0305 while (full_len) {
0306 if (full_len < 254)
0307 full_len = 0;
0308 else
0309 full_len -= 254;
0310 wl3501_get_from_wla(this, this->tx_buffer_head, &next,
0311 sizeof(next));
0312 if (!full_len)
0313 wl3501_set_to_wla(this, this->tx_buffer_head, &zero,
0314 sizeof(zero));
0315 this->tx_buffer_head = next;
0316 blk_cnt++;
0317
0318 if (!next && full_len) {
0319 this->tx_buffer_head = ret;
0320 ret = 0;
0321 goto out;
0322 }
0323 }
0324 this->tx_buffer_cnt -= blk_cnt;
0325 out:
0326 return ret;
0327 }
0328
0329
0330
0331
0332 static void wl3501_free_tx_buffer(struct wl3501_card *this, u16 ptr)
0333 {
0334
0335 if (!this->tx_buffer_head)
0336 this->tx_buffer_head = ptr;
0337 else
0338 wl3501_set_to_wla(this, this->tx_buffer_tail,
0339 &ptr, sizeof(ptr));
0340 while (ptr) {
0341 u16 next;
0342
0343 this->tx_buffer_cnt++;
0344 wl3501_get_from_wla(this, ptr, &next, sizeof(next));
0345 this->tx_buffer_tail = ptr;
0346 ptr = next;
0347 }
0348 }
0349
0350 static int wl3501_esbq_req_test(struct wl3501_card *this)
0351 {
0352 u8 tmp = 0;
0353
0354 wl3501_get_from_wla(this, this->esbq_req_head + 3, &tmp, sizeof(tmp));
0355 return tmp & 0x80;
0356 }
0357
0358 static void wl3501_esbq_req(struct wl3501_card *this, u16 *ptr)
0359 {
0360 u16 tmp = 0;
0361
0362 wl3501_set_to_wla(this, this->esbq_req_head, ptr, 2);
0363 wl3501_set_to_wla(this, this->esbq_req_head + 2, &tmp, sizeof(tmp));
0364 this->esbq_req_head += 4;
0365 if (this->esbq_req_head >= this->esbq_req_end)
0366 this->esbq_req_head = this->esbq_req_start;
0367 }
0368
0369 static int wl3501_esbq_exec(struct wl3501_card *this, void *sig, int sig_size)
0370 {
0371 int rc = -EIO;
0372
0373 if (wl3501_esbq_req_test(this)) {
0374 u16 ptr = wl3501_get_tx_buffer(this, sig_size);
0375 if (ptr) {
0376 wl3501_set_to_wla(this, ptr, sig, sig_size);
0377 wl3501_esbq_req(this, &ptr);
0378 rc = 0;
0379 }
0380 }
0381 return rc;
0382 }
0383
0384 static int wl3501_request_mib(struct wl3501_card *this, u8 index, void *bf)
0385 {
0386 struct wl3501_get_req sig = {
0387 .sig_id = WL3501_SIG_GET_REQ,
0388 .mib_attrib = index,
0389 };
0390 unsigned long flags;
0391 int rc = -EIO;
0392
0393 spin_lock_irqsave(&this->lock, flags);
0394 if (wl3501_esbq_req_test(this)) {
0395 u16 ptr = wl3501_get_tx_buffer(this, sizeof(sig));
0396 if (ptr) {
0397 wl3501_set_to_wla(this, ptr, &sig, sizeof(sig));
0398 wl3501_esbq_req(this, &ptr);
0399 this->sig_get_confirm.mib_status = 255;
0400 rc = 0;
0401 }
0402 }
0403 spin_unlock_irqrestore(&this->lock, flags);
0404
0405 return rc;
0406 }
0407
0408 static int wl3501_get_mib_value(struct wl3501_card *this, u8 index,
0409 void *bf, int size)
0410 {
0411 int rc;
0412
0413 rc = wl3501_request_mib(this, index, bf);
0414 if (rc)
0415 return rc;
0416
0417 rc = wait_event_interruptible(this->wait,
0418 this->sig_get_confirm.mib_status != 255);
0419 if (rc)
0420 return rc;
0421
0422 memcpy(bf, this->sig_get_confirm.mib_value, size);
0423 return 0;
0424 }
0425
0426 static int wl3501_pwr_mgmt(struct wl3501_card *this, int suspend)
0427 {
0428 struct wl3501_pwr_mgmt_req sig = {
0429 .sig_id = WL3501_SIG_PWR_MGMT_REQ,
0430 .pwr_save = suspend,
0431 .wake_up = !suspend,
0432 .receive_dtims = 10,
0433 };
0434 unsigned long flags;
0435 int rc = -EIO;
0436
0437 spin_lock_irqsave(&this->lock, flags);
0438 if (wl3501_esbq_req_test(this)) {
0439 u16 ptr = wl3501_get_tx_buffer(this, sizeof(sig));
0440 if (ptr) {
0441 wl3501_set_to_wla(this, ptr, &sig, sizeof(sig));
0442 wl3501_esbq_req(this, &ptr);
0443 this->sig_pwr_mgmt_confirm.status = 255;
0444 spin_unlock_irqrestore(&this->lock, flags);
0445 rc = wait_event_interruptible(this->wait,
0446 this->sig_pwr_mgmt_confirm.status != 255);
0447 printk(KERN_INFO "%s: %s status=%d\n", __func__,
0448 suspend ? "suspend" : "resume",
0449 this->sig_pwr_mgmt_confirm.status);
0450 goto out;
0451 }
0452 }
0453 spin_unlock_irqrestore(&this->lock, flags);
0454 out:
0455 return rc;
0456 }
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466 static int wl3501_send_pkt(struct wl3501_card *this, u8 *data, u16 len)
0467 {
0468 u16 bf, sig_bf, next, tmplen, pktlen;
0469 struct wl3501_md_req sig = {
0470 .sig_id = WL3501_SIG_MD_REQ,
0471 };
0472 size_t sig_addr_len = sizeof(sig.addr);
0473 u8 *pdata = (char *)data;
0474 int rc = -EIO;
0475
0476 if (wl3501_esbq_req_test(this)) {
0477 sig_bf = wl3501_get_tx_buffer(this, sizeof(sig));
0478 rc = -ENOMEM;
0479 if (!sig_bf)
0480 goto out;
0481 bf = wl3501_get_tx_buffer(this, len + 26 + 24);
0482 if (!bf) {
0483
0484 wl3501_free_tx_buffer(this, sig_bf);
0485 goto out;
0486 }
0487 rc = 0;
0488 memcpy(&sig.addr, pdata, sig_addr_len);
0489 pktlen = len - sig_addr_len;
0490 pdata += sig_addr_len;
0491 sig.data = bf;
0492 if (((*pdata) * 256 + (*(pdata + 1))) > 1500) {
0493 u8 addr4[ETH_ALEN] = {
0494 [0] = 0xAA, [1] = 0xAA, [2] = 0x03, [4] = 0x00,
0495 };
0496
0497 wl3501_set_to_wla(this, bf + 2 +
0498 offsetof(struct wl3501_tx_hdr, addr4),
0499 addr4, sizeof(addr4));
0500 sig.size = pktlen + 24 + 4 + 6;
0501 if (pktlen > (254 - sizeof(struct wl3501_tx_hdr))) {
0502 tmplen = 254 - sizeof(struct wl3501_tx_hdr);
0503 pktlen -= tmplen;
0504 } else {
0505 tmplen = pktlen;
0506 pktlen = 0;
0507 }
0508 wl3501_set_to_wla(this,
0509 bf + 2 + sizeof(struct wl3501_tx_hdr),
0510 pdata, tmplen);
0511 pdata += tmplen;
0512 wl3501_get_from_wla(this, bf, &next, sizeof(next));
0513 bf = next;
0514 } else {
0515 sig.size = pktlen + 24 + 4 - 2;
0516 pdata += 2;
0517 pktlen -= 2;
0518 if (pktlen > (254 - sizeof(struct wl3501_tx_hdr) + 6)) {
0519 tmplen = 254 - sizeof(struct wl3501_tx_hdr) + 6;
0520 pktlen -= tmplen;
0521 } else {
0522 tmplen = pktlen;
0523 pktlen = 0;
0524 }
0525 wl3501_set_to_wla(this, bf + 2 +
0526 offsetof(struct wl3501_tx_hdr, addr4),
0527 pdata, tmplen);
0528 pdata += tmplen;
0529 wl3501_get_from_wla(this, bf, &next, sizeof(next));
0530 bf = next;
0531 }
0532 while (pktlen > 0) {
0533 if (pktlen > 254) {
0534 tmplen = 254;
0535 pktlen -= 254;
0536 } else {
0537 tmplen = pktlen;
0538 pktlen = 0;
0539 }
0540 wl3501_set_to_wla(this, bf + 2, pdata, tmplen);
0541 pdata += tmplen;
0542 wl3501_get_from_wla(this, bf, &next, sizeof(next));
0543 bf = next;
0544 }
0545 wl3501_set_to_wla(this, sig_bf, &sig, sizeof(sig));
0546 wl3501_esbq_req(this, &sig_bf);
0547 }
0548 out:
0549 return rc;
0550 }
0551
0552 static int wl3501_mgmt_resync(struct wl3501_card *this)
0553 {
0554 struct wl3501_resync_req sig = {
0555 .sig_id = WL3501_SIG_RESYNC_REQ,
0556 };
0557
0558 return wl3501_esbq_exec(this, &sig, sizeof(sig));
0559 }
0560
0561 static inline int wl3501_fw_bss_type(struct wl3501_card *this)
0562 {
0563 return this->net_type == IW_MODE_INFRA ? WL3501_NET_TYPE_INFRA :
0564 WL3501_NET_TYPE_ADHOC;
0565 }
0566
0567 static inline int wl3501_fw_cap_info(struct wl3501_card *this)
0568 {
0569 return this->net_type == IW_MODE_INFRA ? WL3501_MGMT_CAPABILITY_ESS :
0570 WL3501_MGMT_CAPABILITY_IBSS;
0571 }
0572
0573 static int wl3501_mgmt_scan(struct wl3501_card *this, u16 chan_time)
0574 {
0575 struct wl3501_scan_req sig = {
0576 .sig_id = WL3501_SIG_SCAN_REQ,
0577 .scan_type = WL3501_SCAN_TYPE_ACTIVE,
0578 .probe_delay = 0x10,
0579 .min_chan_time = chan_time,
0580 .max_chan_time = chan_time,
0581 .bss_type = wl3501_fw_bss_type(this),
0582 };
0583
0584 this->bss_cnt = this->join_sta_bss = 0;
0585 return wl3501_esbq_exec(this, &sig, sizeof(sig));
0586 }
0587
0588 static int wl3501_mgmt_join(struct wl3501_card *this, u16 stas)
0589 {
0590 struct wl3501_join_req sig = {
0591 .sig_id = WL3501_SIG_JOIN_REQ,
0592 .timeout = 10,
0593 .req.ds_pset = {
0594 .el = {
0595 .id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
0596 .len = 1,
0597 },
0598 .chan = this->chan,
0599 },
0600 };
0601
0602 memcpy(&sig.req, &this->bss_set[stas].req, sizeof(sig.req));
0603 return wl3501_esbq_exec(this, &sig, sizeof(sig));
0604 }
0605
0606 static int wl3501_mgmt_start(struct wl3501_card *this)
0607 {
0608 struct wl3501_start_req sig = {
0609 .sig_id = WL3501_SIG_START_REQ,
0610 .beacon_period = 400,
0611 .dtim_period = 1,
0612 .ds_pset = {
0613 .el = {
0614 .id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
0615 .len = 1,
0616 },
0617 .chan = this->chan,
0618 },
0619 .bss_basic_rset = {
0620 .el = {
0621 .id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
0622 .len = 2,
0623 },
0624 .data_rate_labels = {
0625 [0] = IW_MGMT_RATE_LABEL_MANDATORY |
0626 IW_MGMT_RATE_LABEL_1MBIT,
0627 [1] = IW_MGMT_RATE_LABEL_MANDATORY |
0628 IW_MGMT_RATE_LABEL_2MBIT,
0629 },
0630 },
0631 .operational_rset = {
0632 .el = {
0633 .id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
0634 .len = 2,
0635 },
0636 .data_rate_labels = {
0637 [0] = IW_MGMT_RATE_LABEL_MANDATORY |
0638 IW_MGMT_RATE_LABEL_1MBIT,
0639 [1] = IW_MGMT_RATE_LABEL_MANDATORY |
0640 IW_MGMT_RATE_LABEL_2MBIT,
0641 },
0642 },
0643 .ibss_pset = {
0644 .el = {
0645 .id = IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
0646 .len = 2,
0647 },
0648 .atim_window = 10,
0649 },
0650 .bss_type = wl3501_fw_bss_type(this),
0651 .cap_info = wl3501_fw_cap_info(this),
0652 };
0653
0654 iw_copy_mgmt_info_element(&sig.ssid.el, &this->essid.el);
0655 iw_copy_mgmt_info_element(&this->keep_essid.el, &this->essid.el);
0656 return wl3501_esbq_exec(this, &sig, sizeof(sig));
0657 }
0658
0659 static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
0660 {
0661 u16 i = 0;
0662 int matchflag = 0;
0663 struct wl3501_scan_confirm sig;
0664
0665 pr_debug("entry");
0666 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
0667 if (sig.status == WL3501_STATUS_SUCCESS) {
0668 pr_debug("success");
0669 if ((this->net_type == IW_MODE_INFRA &&
0670 (sig.req.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
0671 (this->net_type == IW_MODE_ADHOC &&
0672 (sig.req.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) ||
0673 this->net_type == IW_MODE_AUTO) {
0674 if (!this->essid.el.len)
0675 matchflag = 1;
0676 else if (this->essid.el.len == 3 &&
0677 !memcmp(this->essid.essid, "ANY", 3))
0678 matchflag = 1;
0679 else if (this->essid.el.len != sig.req.ssid.el.len)
0680 matchflag = 0;
0681 else if (memcmp(this->essid.essid, sig.req.ssid.essid,
0682 this->essid.el.len))
0683 matchflag = 0;
0684 else
0685 matchflag = 1;
0686 if (matchflag) {
0687 for (i = 0; i < this->bss_cnt; i++) {
0688 if (ether_addr_equal_unaligned(this->bss_set[i].req.bssid,
0689 sig.req.bssid)) {
0690 matchflag = 0;
0691 break;
0692 }
0693 }
0694 }
0695 if (matchflag && (i < 20)) {
0696 memcpy(&this->bss_set[i].req,
0697 &sig.req, sizeof(sig.req));
0698 this->bss_cnt++;
0699 this->rssi = sig.rssi;
0700 this->bss_set[i].rssi = sig.rssi;
0701 }
0702 }
0703 } else if (sig.status == WL3501_STATUS_TIMEOUT) {
0704 pr_debug("timeout");
0705 this->join_sta_bss = 0;
0706 for (i = this->join_sta_bss; i < this->bss_cnt; i++)
0707 if (!wl3501_mgmt_join(this, i))
0708 break;
0709 this->join_sta_bss = i;
0710 if (this->join_sta_bss == this->bss_cnt) {
0711 if (this->net_type == IW_MODE_INFRA)
0712 wl3501_mgmt_scan(this, 100);
0713 else {
0714 this->adhoc_times++;
0715 if (this->adhoc_times > WL3501_MAX_ADHOC_TRIES)
0716 wl3501_mgmt_start(this);
0717 else
0718 wl3501_mgmt_scan(this, 100);
0719 }
0720 }
0721 }
0722 }
0723
0724
0725
0726
0727
0728
0729
0730
0731 static int wl3501_block_interrupt(struct wl3501_card *this)
0732 {
0733 u8 old = inb(this->base_addr + WL3501_NIC_GCR);
0734 u8 new = old & (~(WL3501_GCR_ECINT | WL3501_GCR_INT2EC |
0735 WL3501_GCR_ENECINT));
0736
0737 wl3501_outb(new, this->base_addr + WL3501_NIC_GCR);
0738 return old & WL3501_GCR_ENECINT;
0739 }
0740
0741
0742
0743
0744
0745
0746
0747
0748 static int wl3501_unblock_interrupt(struct wl3501_card *this)
0749 {
0750 u8 old = inb(this->base_addr + WL3501_NIC_GCR);
0751 u8 new = (old & ~(WL3501_GCR_ECINT | WL3501_GCR_INT2EC)) |
0752 WL3501_GCR_ENECINT;
0753
0754 wl3501_outb(new, this->base_addr + WL3501_NIC_GCR);
0755 return old & WL3501_GCR_ENECINT;
0756 }
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767 static u16 wl3501_receive(struct wl3501_card *this, u8 *bf, u16 size)
0768 {
0769 u16 next_addr, next_addr1;
0770 u8 *data = bf + 12;
0771
0772 size -= 12;
0773 wl3501_get_from_wla(this, this->start_seg + 2,
0774 &next_addr, sizeof(next_addr));
0775 if (size > WL3501_BLKSZ - sizeof(struct wl3501_rx_hdr)) {
0776 wl3501_get_from_wla(this,
0777 this->start_seg +
0778 sizeof(struct wl3501_rx_hdr), data,
0779 WL3501_BLKSZ -
0780 sizeof(struct wl3501_rx_hdr));
0781 size -= WL3501_BLKSZ - sizeof(struct wl3501_rx_hdr);
0782 data += WL3501_BLKSZ - sizeof(struct wl3501_rx_hdr);
0783 } else {
0784 wl3501_get_from_wla(this,
0785 this->start_seg +
0786 sizeof(struct wl3501_rx_hdr),
0787 data, size);
0788 size = 0;
0789 }
0790 while (size > 0) {
0791 if (size > WL3501_BLKSZ - 5) {
0792 wl3501_get_from_wla(this, next_addr + 5, data,
0793 WL3501_BLKSZ - 5);
0794 size -= WL3501_BLKSZ - 5;
0795 data += WL3501_BLKSZ - 5;
0796 wl3501_get_from_wla(this, next_addr + 2, &next_addr1,
0797 sizeof(next_addr1));
0798 next_addr = next_addr1;
0799 } else {
0800 wl3501_get_from_wla(this, next_addr + 5, data, size);
0801 size = 0;
0802 }
0803 }
0804 return 0;
0805 }
0806
0807 static void wl3501_esbq_req_free(struct wl3501_card *this)
0808 {
0809 u8 tmp;
0810 u16 addr;
0811
0812 if (this->esbq_req_head == this->esbq_req_tail)
0813 goto out;
0814 wl3501_get_from_wla(this, this->esbq_req_tail + 3, &tmp, sizeof(tmp));
0815 if (!(tmp & 0x80))
0816 goto out;
0817 wl3501_get_from_wla(this, this->esbq_req_tail, &addr, sizeof(addr));
0818 wl3501_free_tx_buffer(this, addr);
0819 this->esbq_req_tail += 4;
0820 if (this->esbq_req_tail >= this->esbq_req_end)
0821 this->esbq_req_tail = this->esbq_req_start;
0822 out:
0823 return;
0824 }
0825
0826 static int wl3501_esbq_confirm(struct wl3501_card *this)
0827 {
0828 u8 tmp;
0829
0830 wl3501_get_from_wla(this, this->esbq_confirm + 3, &tmp, sizeof(tmp));
0831 return tmp & 0x80;
0832 }
0833
0834 static void wl3501_online(struct net_device *dev)
0835 {
0836 struct wl3501_card *this = netdev_priv(dev);
0837
0838 printk(KERN_INFO "%s: Wireless LAN online. BSSID: %pM\n",
0839 dev->name, this->bssid);
0840 netif_wake_queue(dev);
0841 }
0842
0843 static void wl3501_esbq_confirm_done(struct wl3501_card *this)
0844 {
0845 u8 tmp = 0;
0846
0847 wl3501_set_to_wla(this, this->esbq_confirm + 3, &tmp, sizeof(tmp));
0848 this->esbq_confirm += 4;
0849 if (this->esbq_confirm >= this->esbq_confirm_end)
0850 this->esbq_confirm = this->esbq_confirm_start;
0851 }
0852
0853 static int wl3501_mgmt_auth(struct wl3501_card *this)
0854 {
0855 struct wl3501_auth_req sig = {
0856 .sig_id = WL3501_SIG_AUTH_REQ,
0857 .type = WL3501_SYS_TYPE_OPEN,
0858 .timeout = 1000,
0859 };
0860
0861 pr_debug("entry");
0862 memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
0863 return wl3501_esbq_exec(this, &sig, sizeof(sig));
0864 }
0865
0866 static int wl3501_mgmt_association(struct wl3501_card *this)
0867 {
0868 struct wl3501_assoc_req sig = {
0869 .sig_id = WL3501_SIG_ASSOC_REQ,
0870 .timeout = 1000,
0871 .listen_interval = 5,
0872 .cap_info = this->cap_info,
0873 };
0874
0875 pr_debug("entry");
0876 memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
0877 return wl3501_esbq_exec(this, &sig, sizeof(sig));
0878 }
0879
0880 static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
0881 {
0882 struct wl3501_card *this = netdev_priv(dev);
0883 struct wl3501_join_confirm sig;
0884
0885 pr_debug("entry");
0886 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
0887 if (sig.status == WL3501_STATUS_SUCCESS) {
0888 if (this->net_type == IW_MODE_INFRA) {
0889 if (this->join_sta_bss < this->bss_cnt) {
0890 const int i = this->join_sta_bss;
0891 memcpy(this->bssid,
0892 this->bss_set[i].req.bssid, ETH_ALEN);
0893 this->chan = this->bss_set[i].req.ds_pset.chan;
0894 iw_copy_mgmt_info_element(&this->keep_essid.el,
0895 &this->bss_set[i].req.ssid.el);
0896 wl3501_mgmt_auth(this);
0897 }
0898 } else {
0899 const int i = this->join_sta_bss;
0900
0901 memcpy(&this->bssid, &this->bss_set[i].req.bssid, ETH_ALEN);
0902 this->chan = this->bss_set[i].req.ds_pset.chan;
0903 iw_copy_mgmt_info_element(&this->keep_essid.el,
0904 &this->bss_set[i].req.ssid.el);
0905 wl3501_online(dev);
0906 }
0907 } else {
0908 int i;
0909 this->join_sta_bss++;
0910 for (i = this->join_sta_bss; i < this->bss_cnt; i++)
0911 if (!wl3501_mgmt_join(this, i))
0912 break;
0913 this->join_sta_bss = i;
0914 if (this->join_sta_bss == this->bss_cnt) {
0915 if (this->net_type == IW_MODE_INFRA)
0916 wl3501_mgmt_scan(this, 100);
0917 else {
0918 this->adhoc_times++;
0919 if (this->adhoc_times > WL3501_MAX_ADHOC_TRIES)
0920 wl3501_mgmt_start(this);
0921 else
0922 wl3501_mgmt_scan(this, 100);
0923 }
0924 }
0925 }
0926 }
0927
0928 static inline void wl3501_alarm_interrupt(struct net_device *dev,
0929 struct wl3501_card *this)
0930 {
0931 if (this->net_type == IW_MODE_INFRA) {
0932 printk(KERN_INFO "Wireless LAN offline\n");
0933 netif_stop_queue(dev);
0934 wl3501_mgmt_resync(this);
0935 }
0936 }
0937
0938 static inline void wl3501_md_confirm_interrupt(struct net_device *dev,
0939 struct wl3501_card *this,
0940 u16 addr)
0941 {
0942 struct wl3501_md_confirm sig;
0943
0944 pr_debug("entry");
0945 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
0946 wl3501_free_tx_buffer(this, sig.data);
0947 if (netif_queue_stopped(dev))
0948 netif_wake_queue(dev);
0949 }
0950
0951 static inline void wl3501_md_ind_interrupt(struct net_device *dev,
0952 struct wl3501_card *this, u16 addr)
0953 {
0954 struct wl3501_md_ind sig;
0955 struct sk_buff *skb;
0956 u8 rssi, addr4[ETH_ALEN];
0957 u16 pkt_len;
0958
0959 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
0960 this->start_seg = sig.data;
0961 wl3501_get_from_wla(this,
0962 sig.data + offsetof(struct wl3501_rx_hdr, rssi),
0963 &rssi, sizeof(rssi));
0964 this->rssi = rssi <= 63 ? (rssi * 100) / 64 : 255;
0965
0966 wl3501_get_from_wla(this,
0967 sig.data +
0968 offsetof(struct wl3501_rx_hdr, addr4),
0969 &addr4, sizeof(addr4));
0970 if (!(addr4[0] == 0xAA && addr4[1] == 0xAA &&
0971 addr4[2] == 0x03 && addr4[4] == 0x00)) {
0972 printk(KERN_INFO "Unsupported packet type!\n");
0973 return;
0974 }
0975 pkt_len = sig.size + 12 - 24 - 4 - 6;
0976
0977 skb = dev_alloc_skb(pkt_len + 5);
0978
0979 if (!skb) {
0980 printk(KERN_WARNING "%s: Can't alloc a sk_buff of size %d.\n",
0981 dev->name, pkt_len);
0982 dev->stats.rx_dropped++;
0983 } else {
0984 skb->dev = dev;
0985 skb_reserve(skb, 2);
0986 skb_copy_to_linear_data(skb, (unsigned char *)&sig.addr,
0987 sizeof(sig.addr));
0988 wl3501_receive(this, skb->data, pkt_len);
0989 skb_put(skb, pkt_len);
0990 skb->protocol = eth_type_trans(skb, dev);
0991 dev->stats.rx_packets++;
0992 dev->stats.rx_bytes += skb->len;
0993 netif_rx(skb);
0994 }
0995 }
0996
0997 static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this,
0998 u16 addr, void *sig, int size)
0999 {
1000 pr_debug("entry");
1001 wl3501_get_from_wla(this, addr, &this->sig_get_confirm,
1002 sizeof(this->sig_get_confirm));
1003 wake_up(&this->wait);
1004 }
1005
1006 static inline void wl3501_start_confirm_interrupt(struct net_device *dev,
1007 struct wl3501_card *this,
1008 u16 addr)
1009 {
1010 struct wl3501_start_confirm sig;
1011
1012 pr_debug("entry");
1013 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
1014 if (sig.status == WL3501_STATUS_SUCCESS)
1015 netif_wake_queue(dev);
1016 }
1017
1018 static inline void wl3501_assoc_confirm_interrupt(struct net_device *dev,
1019 u16 addr)
1020 {
1021 struct wl3501_card *this = netdev_priv(dev);
1022 struct wl3501_assoc_confirm sig;
1023
1024 pr_debug("entry");
1025 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
1026
1027 if (sig.status == WL3501_STATUS_SUCCESS)
1028 wl3501_online(dev);
1029 }
1030
1031 static inline void wl3501_auth_confirm_interrupt(struct wl3501_card *this,
1032 u16 addr)
1033 {
1034 struct wl3501_auth_confirm sig;
1035
1036 pr_debug("entry");
1037 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
1038
1039 if (sig.status == WL3501_STATUS_SUCCESS)
1040 wl3501_mgmt_association(this);
1041 else
1042 wl3501_mgmt_resync(this);
1043 }
1044
1045 static inline void wl3501_rx_interrupt(struct net_device *dev)
1046 {
1047 int morepkts;
1048 u16 addr;
1049 u8 sig_id;
1050 struct wl3501_card *this = netdev_priv(dev);
1051
1052 pr_debug("entry");
1053 loop:
1054 morepkts = 0;
1055 if (!wl3501_esbq_confirm(this))
1056 goto free;
1057 wl3501_get_from_wla(this, this->esbq_confirm, &addr, sizeof(addr));
1058 wl3501_get_from_wla(this, addr + 2, &sig_id, sizeof(sig_id));
1059
1060 switch (sig_id) {
1061 case WL3501_SIG_DEAUTH_IND:
1062 case WL3501_SIG_DISASSOC_IND:
1063 case WL3501_SIG_ALARM:
1064 wl3501_alarm_interrupt(dev, this);
1065 break;
1066 case WL3501_SIG_MD_CONFIRM:
1067 wl3501_md_confirm_interrupt(dev, this, addr);
1068 break;
1069 case WL3501_SIG_MD_IND:
1070 wl3501_md_ind_interrupt(dev, this, addr);
1071 break;
1072 case WL3501_SIG_GET_CONFIRM:
1073 wl3501_get_confirm_interrupt(this, addr,
1074 &this->sig_get_confirm,
1075 sizeof(this->sig_get_confirm));
1076 break;
1077 case WL3501_SIG_PWR_MGMT_CONFIRM:
1078 wl3501_get_confirm_interrupt(this, addr,
1079 &this->sig_pwr_mgmt_confirm,
1080 sizeof(this->sig_pwr_mgmt_confirm));
1081 break;
1082 case WL3501_SIG_START_CONFIRM:
1083 wl3501_start_confirm_interrupt(dev, this, addr);
1084 break;
1085 case WL3501_SIG_SCAN_CONFIRM:
1086 wl3501_mgmt_scan_confirm(this, addr);
1087 break;
1088 case WL3501_SIG_JOIN_CONFIRM:
1089 wl3501_mgmt_join_confirm(dev, addr);
1090 break;
1091 case WL3501_SIG_ASSOC_CONFIRM:
1092 wl3501_assoc_confirm_interrupt(dev, addr);
1093 break;
1094 case WL3501_SIG_AUTH_CONFIRM:
1095 wl3501_auth_confirm_interrupt(this, addr);
1096 break;
1097 case WL3501_SIG_RESYNC_CONFIRM:
1098 wl3501_mgmt_resync(this);
1099 break;
1100 }
1101 wl3501_esbq_confirm_done(this);
1102 morepkts = 1;
1103
1104 free:
1105 wl3501_esbq_req_free(this);
1106 if (morepkts)
1107 goto loop;
1108 }
1109
1110 static inline void wl3501_ack_interrupt(struct wl3501_card *this)
1111 {
1112 wl3501_outb(WL3501_GCR_ECINT, this->base_addr + WL3501_NIC_GCR);
1113 }
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127 static irqreturn_t wl3501_interrupt(int irq, void *dev_id)
1128 {
1129 struct net_device *dev = dev_id;
1130 struct wl3501_card *this;
1131
1132 this = netdev_priv(dev);
1133 spin_lock(&this->lock);
1134 wl3501_ack_interrupt(this);
1135 wl3501_block_interrupt(this);
1136 wl3501_rx_interrupt(dev);
1137 wl3501_unblock_interrupt(this);
1138 spin_unlock(&this->lock);
1139
1140 return IRQ_HANDLED;
1141 }
1142
1143 static int wl3501_reset_board(struct wl3501_card *this)
1144 {
1145 u8 tmp = 0;
1146 int i, rc = 0;
1147
1148
1149 wl3501_outb_p(WL3501_GCR_CORESET, this->base_addr + WL3501_NIC_GCR);
1150 wl3501_outb_p(0, this->base_addr + WL3501_NIC_GCR);
1151 wl3501_outb_p(WL3501_GCR_CORESET, this->base_addr + WL3501_NIC_GCR);
1152
1153
1154 wl3501_set_to_wla(this, 0x480, &tmp, sizeof(tmp));
1155
1156
1157 wl3501_outb_p(0, this->base_addr + WL3501_NIC_GCR);
1158
1159 WL3501_NOPLOOP(1024 * 50);
1160
1161 wl3501_unblock_interrupt(this);
1162
1163
1164 for (i = 0; i < 10000; i++) {
1165 wl3501_get_from_wla(this, 0x480, &tmp, sizeof(tmp));
1166
1167 if (tmp == 'W') {
1168
1169 tmp = 'A';
1170 wl3501_set_to_wla(this, 0x480, &tmp, sizeof(tmp));
1171 goto out;
1172 }
1173 WL3501_NOPLOOP(10);
1174 }
1175 printk(KERN_WARNING "%s: failed to reset the board!\n", __func__);
1176 rc = -ENODEV;
1177 out:
1178 return rc;
1179 }
1180
1181 static int wl3501_init_firmware(struct wl3501_card *this)
1182 {
1183 u16 ptr, next;
1184 int rc = wl3501_reset_board(this);
1185
1186 if (rc)
1187 goto fail;
1188 this->card_name[0] = '\0';
1189 wl3501_get_from_wla(this, 0x1a00,
1190 this->card_name, sizeof(this->card_name));
1191 this->card_name[sizeof(this->card_name) - 1] = '\0';
1192 this->firmware_date[0] = '\0';
1193 wl3501_get_from_wla(this, 0x1a40,
1194 this->firmware_date, sizeof(this->firmware_date));
1195 this->firmware_date[sizeof(this->firmware_date) - 1] = '\0';
1196
1197 wl3501_switch_page(this, WL3501_BSS_SPAGE0);
1198
1199 wl3501_get_from_wla(this, 0x482, &this->esbq_req_start, 2);
1200 wl3501_get_from_wla(this, 0x486, &this->esbq_req_end, 2);
1201 wl3501_get_from_wla(this, 0x488, &this->esbq_confirm_start, 2);
1202 wl3501_get_from_wla(this, 0x48c, &this->esbq_confirm_end, 2);
1203 wl3501_get_from_wla(this, 0x48e, &this->tx_buffer_head, 2);
1204 wl3501_get_from_wla(this, 0x492, &this->tx_buffer_size, 2);
1205 this->esbq_req_tail = this->esbq_req_head = this->esbq_req_start;
1206 this->esbq_req_end += this->esbq_req_start;
1207 this->esbq_confirm = this->esbq_confirm_start;
1208 this->esbq_confirm_end += this->esbq_confirm_start;
1209
1210 this->tx_buffer_cnt = 1;
1211 ptr = this->tx_buffer_head;
1212 next = ptr + WL3501_BLKSZ;
1213 while ((next - this->tx_buffer_head) < this->tx_buffer_size) {
1214 this->tx_buffer_cnt++;
1215 wl3501_set_to_wla(this, ptr, &next, sizeof(next));
1216 ptr = next;
1217 next = ptr + WL3501_BLKSZ;
1218 }
1219 rc = 0;
1220 next = 0;
1221 wl3501_set_to_wla(this, ptr, &next, sizeof(next));
1222 this->tx_buffer_tail = ptr;
1223 out:
1224 return rc;
1225 fail:
1226 printk(KERN_WARNING "%s: failed!\n", __func__);
1227 goto out;
1228 }
1229
1230 static int wl3501_close(struct net_device *dev)
1231 {
1232 struct wl3501_card *this = netdev_priv(dev);
1233 unsigned long flags;
1234 struct pcmcia_device *link;
1235 link = this->p_dev;
1236
1237 spin_lock_irqsave(&this->lock, flags);
1238 link->open--;
1239
1240
1241 netif_stop_queue(dev);
1242 wl3501_ack_interrupt(this);
1243
1244
1245 wl3501_block_interrupt(this);
1246
1247 printk(KERN_INFO "%s: WL3501 closed\n", dev->name);
1248 spin_unlock_irqrestore(&this->lock, flags);
1249 return 0;
1250 }
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260 static int wl3501_reset(struct net_device *dev)
1261 {
1262 struct wl3501_card *this = netdev_priv(dev);
1263 int rc = -ENODEV;
1264 unsigned long flags;
1265
1266 spin_lock_irqsave(&this->lock, flags);
1267 wl3501_block_interrupt(this);
1268
1269 if (wl3501_init_firmware(this)) {
1270 printk(KERN_WARNING "%s: Can't initialize Firmware!\n",
1271 dev->name);
1272
1273 free_irq(dev->irq, dev);
1274 goto out;
1275 }
1276
1277
1278
1279
1280 netif_stop_queue(dev);
1281 this->adhoc_times = 0;
1282 wl3501_ack_interrupt(this);
1283 wl3501_unblock_interrupt(this);
1284 wl3501_mgmt_scan(this, 100);
1285 pr_debug("%s: device reset", dev->name);
1286 rc = 0;
1287 out:
1288 spin_unlock_irqrestore(&this->lock, flags);
1289 return rc;
1290 }
1291
1292 static void wl3501_tx_timeout(struct net_device *dev, unsigned int txqueue)
1293 {
1294 struct net_device_stats *stats = &dev->stats;
1295 int rc;
1296
1297 stats->tx_errors++;
1298 rc = wl3501_reset(dev);
1299 if (rc)
1300 printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",
1301 dev->name, rc);
1302 else {
1303 netif_trans_update(dev);
1304 netif_wake_queue(dev);
1305 }
1306 }
1307
1308
1309
1310
1311
1312
1313 static netdev_tx_t wl3501_hard_start_xmit(struct sk_buff *skb,
1314 struct net_device *dev)
1315 {
1316 int enabled, rc;
1317 struct wl3501_card *this = netdev_priv(dev);
1318 unsigned long flags;
1319
1320 spin_lock_irqsave(&this->lock, flags);
1321 enabled = wl3501_block_interrupt(this);
1322 rc = wl3501_send_pkt(this, skb->data, skb->len);
1323 if (enabled)
1324 wl3501_unblock_interrupt(this);
1325 if (rc) {
1326 ++dev->stats.tx_dropped;
1327 netif_stop_queue(dev);
1328 } else {
1329 ++dev->stats.tx_packets;
1330 dev->stats.tx_bytes += skb->len;
1331 kfree_skb(skb);
1332
1333 if (this->tx_buffer_cnt < 2)
1334 netif_stop_queue(dev);
1335 }
1336 spin_unlock_irqrestore(&this->lock, flags);
1337 return NETDEV_TX_OK;
1338 }
1339
1340 static int wl3501_open(struct net_device *dev)
1341 {
1342 int rc = -ENODEV;
1343 struct wl3501_card *this = netdev_priv(dev);
1344 unsigned long flags;
1345 struct pcmcia_device *link;
1346 link = this->p_dev;
1347
1348 spin_lock_irqsave(&this->lock, flags);
1349 if (!pcmcia_dev_present(link))
1350 goto out;
1351 netif_device_attach(dev);
1352 link->open++;
1353
1354
1355 pr_debug("%s: Initialize WL3501 firmware...", dev->name);
1356 if (wl3501_init_firmware(this))
1357 goto fail;
1358
1359 this->adhoc_times = 0;
1360
1361 wl3501_ack_interrupt(this);
1362
1363
1364 wl3501_unblock_interrupt(this);
1365 wl3501_mgmt_scan(this, 100);
1366 rc = 0;
1367 pr_debug("%s: WL3501 opened", dev->name);
1368 printk(KERN_INFO "%s: Card Name: %s\n"
1369 "%s: Firmware Date: %s\n",
1370 dev->name, this->card_name,
1371 dev->name, this->firmware_date);
1372 out:
1373 spin_unlock_irqrestore(&this->lock, flags);
1374 return rc;
1375 fail:
1376 printk(KERN_WARNING "%s: Can't initialize firmware!\n", dev->name);
1377 goto out;
1378 }
1379
1380 static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
1381 {
1382 struct wl3501_card *this = netdev_priv(dev);
1383 struct iw_statistics *wstats = &this->wstats;
1384 u32 value;
1385
1386 memset(wstats, 0, sizeof(*wstats));
1387 wstats->status = netif_running(dev);
1388 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_ICV_ERROR_COUNT,
1389 &value, sizeof(value)))
1390 wstats->discard.code += value;
1391 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_UNDECRYPTABLE_COUNT,
1392 &value, sizeof(value)))
1393 wstats->discard.code += value;
1394 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_EXCLUDED_COUNT,
1395 &value, sizeof(value)))
1396 wstats->discard.code += value;
1397 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_RETRY_COUNT,
1398 &value, sizeof(value)))
1399 wstats->discard.retries = value;
1400 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_FAILED_COUNT,
1401 &value, sizeof(value)))
1402 wstats->discard.misc += value;
1403 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_RTS_FAILURE_COUNT,
1404 &value, sizeof(value)))
1405 wstats->discard.misc += value;
1406 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_ACK_FAILURE_COUNT,
1407 &value, sizeof(value)))
1408 wstats->discard.misc += value;
1409 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_FRAME_DUPLICATE_COUNT,
1410 &value, sizeof(value)))
1411 wstats->discard.misc += value;
1412 return wstats;
1413 }
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423 static void wl3501_detach(struct pcmcia_device *link)
1424 {
1425 struct net_device *dev = link->priv;
1426
1427
1428
1429
1430
1431 while (link->open > 0)
1432 wl3501_close(dev);
1433
1434 netif_device_detach(dev);
1435 wl3501_release(link);
1436
1437 unregister_netdev(dev);
1438 free_netdev(dev);
1439 }
1440
1441 static int wl3501_get_name(struct net_device *dev, struct iw_request_info *info,
1442 union iwreq_data *wrqu, char *extra)
1443 {
1444 strlcpy(wrqu->name, "IEEE 802.11-DS", sizeof(wrqu->name));
1445 return 0;
1446 }
1447
1448 static int wl3501_set_freq(struct net_device *dev, struct iw_request_info *info,
1449 union iwreq_data *wrqu, char *extra)
1450 {
1451 struct wl3501_card *this = netdev_priv(dev);
1452 int channel = wrqu->freq.m;
1453 int rc = -EINVAL;
1454
1455 if (iw_valid_channel(this->reg_domain, channel)) {
1456 this->chan = channel;
1457 rc = wl3501_reset(dev);
1458 }
1459 return rc;
1460 }
1461
1462 static int wl3501_get_freq(struct net_device *dev, struct iw_request_info *info,
1463 union iwreq_data *wrqu, char *extra)
1464 {
1465 struct wl3501_card *this = netdev_priv(dev);
1466
1467 wrqu->freq.m = 100000 *
1468 ieee80211_channel_to_frequency(this->chan, NL80211_BAND_2GHZ);
1469 wrqu->freq.e = 1;
1470 return 0;
1471 }
1472
1473 static int wl3501_set_mode(struct net_device *dev, struct iw_request_info *info,
1474 union iwreq_data *wrqu, char *extra)
1475 {
1476 int rc = -EINVAL;
1477
1478 if (wrqu->mode == IW_MODE_INFRA ||
1479 wrqu->mode == IW_MODE_ADHOC ||
1480 wrqu->mode == IW_MODE_AUTO) {
1481 struct wl3501_card *this = netdev_priv(dev);
1482
1483 this->net_type = wrqu->mode;
1484 rc = wl3501_reset(dev);
1485 }
1486 return rc;
1487 }
1488
1489 static int wl3501_get_mode(struct net_device *dev, struct iw_request_info *info,
1490 union iwreq_data *wrqu, char *extra)
1491 {
1492 struct wl3501_card *this = netdev_priv(dev);
1493
1494 wrqu->mode = this->net_type;
1495 return 0;
1496 }
1497
1498 static int wl3501_get_sens(struct net_device *dev, struct iw_request_info *info,
1499 union iwreq_data *wrqu, char *extra)
1500 {
1501 struct wl3501_card *this = netdev_priv(dev);
1502
1503 wrqu->sens.value = this->rssi;
1504 wrqu->sens.disabled = !wrqu->sens.value;
1505 wrqu->sens.fixed = 1;
1506 return 0;
1507 }
1508
1509 static int wl3501_get_range(struct net_device *dev,
1510 struct iw_request_info *info,
1511 union iwreq_data *wrqu, char *extra)
1512 {
1513 struct iw_range *range = (struct iw_range *)extra;
1514
1515
1516 wrqu->data.length = sizeof(*range);
1517
1518
1519 memset(range, 0, sizeof(*range));
1520
1521
1522 range->we_version_compiled = WIRELESS_EXT;
1523 range->we_version_source = 1;
1524 range->throughput = 2 * 1000 * 1000;
1525
1526 return 0;
1527 }
1528
1529 static int wl3501_set_wap(struct net_device *dev, struct iw_request_info *info,
1530 union iwreq_data *wrqu, char *extra)
1531 {
1532 struct wl3501_card *this = netdev_priv(dev);
1533 int rc = -EINVAL;
1534
1535
1536 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
1537 goto out;
1538 if (is_broadcast_ether_addr(wrqu->ap_addr.sa_data)) {
1539
1540 } else
1541 memcpy(this->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
1542
1543 rc = 0;
1544 out:
1545 return rc;
1546 }
1547
1548 static int wl3501_get_wap(struct net_device *dev, struct iw_request_info *info,
1549 union iwreq_data *wrqu, char *extra)
1550 {
1551 struct wl3501_card *this = netdev_priv(dev);
1552
1553 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1554 memcpy(wrqu->ap_addr.sa_data, this->bssid, ETH_ALEN);
1555 return 0;
1556 }
1557
1558 static int wl3501_set_scan(struct net_device *dev, struct iw_request_info *info,
1559 union iwreq_data *wrqu, char *extra)
1560 {
1561
1562
1563
1564 return wl3501_reset(dev);
1565 }
1566
1567 static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
1568 union iwreq_data *wrqu, char *extra)
1569 {
1570 struct wl3501_card *this = netdev_priv(dev);
1571 int i;
1572 char *current_ev = extra;
1573 struct iw_event iwe;
1574
1575 for (i = 0; i < this->bss_cnt; ++i) {
1576 iwe.cmd = SIOCGIWAP;
1577 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1578 memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].req.bssid, ETH_ALEN);
1579 current_ev = iwe_stream_add_event(info, current_ev,
1580 extra + IW_SCAN_MAX_DATA,
1581 &iwe, IW_EV_ADDR_LEN);
1582 iwe.cmd = SIOCGIWESSID;
1583 iwe.u.data.flags = 1;
1584 iwe.u.data.length = this->bss_set[i].req.ssid.el.len;
1585 current_ev = iwe_stream_add_point(info, current_ev,
1586 extra + IW_SCAN_MAX_DATA,
1587 &iwe,
1588 this->bss_set[i].req.ssid.essid);
1589 iwe.cmd = SIOCGIWMODE;
1590 iwe.u.mode = this->bss_set[i].req.bss_type;
1591 current_ev = iwe_stream_add_event(info, current_ev,
1592 extra + IW_SCAN_MAX_DATA,
1593 &iwe, IW_EV_UINT_LEN);
1594 iwe.cmd = SIOCGIWFREQ;
1595 iwe.u.freq.m = this->bss_set[i].req.ds_pset.chan;
1596 iwe.u.freq.e = 0;
1597 current_ev = iwe_stream_add_event(info, current_ev,
1598 extra + IW_SCAN_MAX_DATA,
1599 &iwe, IW_EV_FREQ_LEN);
1600 iwe.cmd = SIOCGIWENCODE;
1601 if (this->bss_set[i].req.cap_info & WL3501_MGMT_CAPABILITY_PRIVACY)
1602 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1603 else
1604 iwe.u.data.flags = IW_ENCODE_DISABLED;
1605 iwe.u.data.length = 0;
1606 current_ev = iwe_stream_add_point(info, current_ev,
1607 extra + IW_SCAN_MAX_DATA,
1608 &iwe, NULL);
1609 }
1610
1611 wrqu->data.length = (current_ev - extra);
1612 wrqu->data.flags = 0;
1613 return 0;
1614 }
1615
1616 static int wl3501_set_essid(struct net_device *dev,
1617 struct iw_request_info *info,
1618 union iwreq_data *wrqu, char *extra)
1619 {
1620 struct wl3501_card *this = netdev_priv(dev);
1621
1622 if (wrqu->data.flags) {
1623 iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID,
1624 &this->essid.el,
1625 extra, wrqu->data.length);
1626 } else {
1627 iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID,
1628 &this->essid.el, "ANY", 3);
1629 }
1630 return wl3501_reset(dev);
1631 }
1632
1633 static int wl3501_get_essid(struct net_device *dev,
1634 struct iw_request_info *info,
1635 union iwreq_data *wrqu, char *extra)
1636 {
1637 struct wl3501_card *this = netdev_priv(dev);
1638 unsigned long flags;
1639
1640 spin_lock_irqsave(&this->lock, flags);
1641 wrqu->essid.flags = 1;
1642 wrqu->essid.length = this->essid.el.len;
1643 memcpy(extra, this->essid.essid, this->essid.el.len);
1644 spin_unlock_irqrestore(&this->lock, flags);
1645 return 0;
1646 }
1647
1648 static int wl3501_set_nick(struct net_device *dev, struct iw_request_info *info,
1649 union iwreq_data *wrqu, char *extra)
1650 {
1651 struct wl3501_card *this = netdev_priv(dev);
1652
1653 if (wrqu->data.length > sizeof(this->nick))
1654 return -E2BIG;
1655 strlcpy(this->nick, extra, wrqu->data.length);
1656 return 0;
1657 }
1658
1659 static int wl3501_get_nick(struct net_device *dev, struct iw_request_info *info,
1660 union iwreq_data *wrqu, char *extra)
1661 {
1662 struct wl3501_card *this = netdev_priv(dev);
1663
1664 strlcpy(extra, this->nick, 32);
1665 wrqu->data.length = strlen(extra);
1666 return 0;
1667 }
1668
1669 static int wl3501_get_rate(struct net_device *dev, struct iw_request_info *info,
1670 union iwreq_data *wrqu, char *extra)
1671 {
1672
1673
1674
1675
1676
1677 wrqu->bitrate.value = 2000000;
1678 wrqu->bitrate.fixed = 1;
1679 return 0;
1680 }
1681
1682 static int wl3501_get_rts_threshold(struct net_device *dev,
1683 struct iw_request_info *info,
1684 union iwreq_data *wrqu, char *extra)
1685 {
1686 u16 threshold;
1687 struct wl3501_card *this = netdev_priv(dev);
1688 int rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_RTS_THRESHOLD,
1689 &threshold, sizeof(threshold));
1690 if (!rc) {
1691 wrqu->rts.value = threshold;
1692 wrqu->rts.disabled = threshold >= 2347;
1693 wrqu->rts.fixed = 1;
1694 }
1695 return rc;
1696 }
1697
1698 static int wl3501_get_frag_threshold(struct net_device *dev,
1699 struct iw_request_info *info,
1700 union iwreq_data *wrqu, char *extra)
1701 {
1702 u16 threshold;
1703 struct wl3501_card *this = netdev_priv(dev);
1704 int rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_FRAG_THRESHOLD,
1705 &threshold, sizeof(threshold));
1706 if (!rc) {
1707 wrqu->frag.value = threshold;
1708 wrqu->frag.disabled = threshold >= 2346;
1709 wrqu->frag.fixed = 1;
1710 }
1711 return rc;
1712 }
1713
1714 static int wl3501_get_txpow(struct net_device *dev,
1715 struct iw_request_info *info,
1716 union iwreq_data *wrqu, char *extra)
1717 {
1718 u16 txpow;
1719 struct wl3501_card *this = netdev_priv(dev);
1720 int rc = wl3501_get_mib_value(this,
1721 WL3501_MIB_ATTR_CURRENT_TX_PWR_LEVEL,
1722 &txpow, sizeof(txpow));
1723 if (!rc) {
1724 wrqu->txpower.value = txpow;
1725 wrqu->txpower.disabled = 0;
1726
1727
1728
1729
1730 wrqu->txpower.fixed = 0;
1731 wrqu->txpower.flags = IW_TXPOW_MWATT;
1732 }
1733 return rc;
1734 }
1735
1736 static int wl3501_get_retry(struct net_device *dev,
1737 struct iw_request_info *info,
1738 union iwreq_data *wrqu, char *extra)
1739 {
1740 u8 retry;
1741 struct wl3501_card *this = netdev_priv(dev);
1742 int rc = wl3501_get_mib_value(this,
1743 WL3501_MIB_ATTR_LONG_RETRY_LIMIT,
1744 &retry, sizeof(retry));
1745 if (rc)
1746 goto out;
1747 if (wrqu->retry.flags & IW_RETRY_LONG) {
1748 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1749 goto set_value;
1750 }
1751 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT,
1752 &retry, sizeof(retry));
1753 if (rc)
1754 goto out;
1755 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
1756 set_value:
1757 wrqu->retry.value = retry;
1758 wrqu->retry.disabled = 0;
1759 out:
1760 return rc;
1761 }
1762
1763 static int wl3501_get_encode(struct net_device *dev,
1764 struct iw_request_info *info,
1765 union iwreq_data *wrqu, char *extra)
1766 {
1767 u8 implemented, restricted, keys[100], len_keys, tocopy;
1768 struct wl3501_card *this = netdev_priv(dev);
1769 int rc = wl3501_get_mib_value(this,
1770 WL3501_MIB_ATTR_PRIV_OPT_IMPLEMENTED,
1771 &implemented, sizeof(implemented));
1772 if (rc)
1773 goto out;
1774 if (!implemented) {
1775 wrqu->encoding.flags = IW_ENCODE_DISABLED;
1776 goto out;
1777 }
1778 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_EXCLUDE_UNENCRYPTED,
1779 &restricted, sizeof(restricted));
1780 if (rc)
1781 goto out;
1782 wrqu->encoding.flags = restricted ? IW_ENCODE_RESTRICTED :
1783 IW_ENCODE_OPEN;
1784 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_KEY_MAPPINGS_LEN,
1785 &len_keys, sizeof(len_keys));
1786 if (rc)
1787 goto out;
1788 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_KEY_MAPPINGS,
1789 keys, len_keys);
1790 if (rc)
1791 goto out;
1792 tocopy = min_t(u16, len_keys, wrqu->encoding.length);
1793 tocopy = min_t(u8, tocopy, 100);
1794 wrqu->encoding.length = tocopy;
1795 memcpy(extra, keys, tocopy);
1796 out:
1797 return rc;
1798 }
1799
1800 static int wl3501_get_power(struct net_device *dev,
1801 struct iw_request_info *info,
1802 union iwreq_data *wrqu, char *extra)
1803 {
1804 u8 pwr_state;
1805 struct wl3501_card *this = netdev_priv(dev);
1806 int rc = wl3501_get_mib_value(this,
1807 WL3501_MIB_ATTR_CURRENT_PWR_STATE,
1808 &pwr_state, sizeof(pwr_state));
1809 if (rc)
1810 goto out;
1811 wrqu->power.disabled = !pwr_state;
1812 wrqu->power.flags = IW_POWER_ON;
1813 out:
1814 return rc;
1815 }
1816
1817 static const iw_handler wl3501_handler[] = {
1818 IW_HANDLER(SIOCGIWNAME, wl3501_get_name),
1819 IW_HANDLER(SIOCSIWFREQ, wl3501_set_freq),
1820 IW_HANDLER(SIOCGIWFREQ, wl3501_get_freq),
1821 IW_HANDLER(SIOCSIWMODE, wl3501_set_mode),
1822 IW_HANDLER(SIOCGIWMODE, wl3501_get_mode),
1823 IW_HANDLER(SIOCGIWSENS, wl3501_get_sens),
1824 IW_HANDLER(SIOCGIWRANGE, wl3501_get_range),
1825 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1826 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1827 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1828 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1829 IW_HANDLER(SIOCSIWAP, wl3501_set_wap),
1830 IW_HANDLER(SIOCGIWAP, wl3501_get_wap),
1831 IW_HANDLER(SIOCSIWSCAN, wl3501_set_scan),
1832 IW_HANDLER(SIOCGIWSCAN, wl3501_get_scan),
1833 IW_HANDLER(SIOCSIWESSID, wl3501_set_essid),
1834 IW_HANDLER(SIOCGIWESSID, wl3501_get_essid),
1835 IW_HANDLER(SIOCSIWNICKN, wl3501_set_nick),
1836 IW_HANDLER(SIOCGIWNICKN, wl3501_get_nick),
1837 IW_HANDLER(SIOCGIWRATE, wl3501_get_rate),
1838 IW_HANDLER(SIOCGIWRTS, wl3501_get_rts_threshold),
1839 IW_HANDLER(SIOCGIWFRAG, wl3501_get_frag_threshold),
1840 IW_HANDLER(SIOCGIWTXPOW, wl3501_get_txpow),
1841 IW_HANDLER(SIOCGIWRETRY, wl3501_get_retry),
1842 IW_HANDLER(SIOCGIWENCODE, wl3501_get_encode),
1843 IW_HANDLER(SIOCGIWPOWER, wl3501_get_power),
1844 };
1845
1846 static const struct iw_handler_def wl3501_handler_def = {
1847 .num_standard = ARRAY_SIZE(wl3501_handler),
1848 .standard = (iw_handler *)wl3501_handler,
1849 .get_wireless_stats = wl3501_get_wireless_stats,
1850 };
1851
1852 static const struct net_device_ops wl3501_netdev_ops = {
1853 .ndo_open = wl3501_open,
1854 .ndo_stop = wl3501_close,
1855 .ndo_start_xmit = wl3501_hard_start_xmit,
1856 .ndo_tx_timeout = wl3501_tx_timeout,
1857 .ndo_set_mac_address = eth_mac_addr,
1858 .ndo_validate_addr = eth_validate_addr,
1859 };
1860
1861 static int wl3501_probe(struct pcmcia_device *p_dev)
1862 {
1863 struct net_device *dev;
1864 struct wl3501_card *this;
1865
1866
1867 p_dev->resource[0]->end = 16;
1868 p_dev->resource[0]->flags = IO_DATA_PATH_WIDTH_8;
1869
1870
1871 p_dev->config_flags = CONF_ENABLE_IRQ;
1872 p_dev->config_index = 1;
1873
1874 dev = alloc_etherdev(sizeof(struct wl3501_card));
1875 if (!dev)
1876 goto out_link;
1877
1878
1879 dev->netdev_ops = &wl3501_netdev_ops;
1880 dev->watchdog_timeo = 5 * HZ;
1881
1882 this = netdev_priv(dev);
1883 this->wireless_data.spy_data = &this->spy_data;
1884 this->p_dev = p_dev;
1885 dev->wireless_data = &this->wireless_data;
1886 dev->wireless_handlers = &wl3501_handler_def;
1887 netif_stop_queue(dev);
1888 p_dev->priv = dev;
1889
1890 return wl3501_config(p_dev);
1891 out_link:
1892 return -ENOMEM;
1893 }
1894
1895 static int wl3501_config(struct pcmcia_device *link)
1896 {
1897 struct net_device *dev = link->priv;
1898 int i = 0, j, ret;
1899 struct wl3501_card *this;
1900
1901
1902
1903
1904 link->io_lines = 5;
1905
1906 for (j = 0x280; j < 0x400; j += 0x20) {
1907
1908
1909 link->resource[0]->start = j;
1910 link->resource[1]->start = link->resource[0]->start + 0x10;
1911 i = pcmcia_request_io(link);
1912 if (i == 0)
1913 break;
1914 }
1915 if (i != 0)
1916 goto failed;
1917
1918
1919
1920
1921 ret = pcmcia_request_irq(link, wl3501_interrupt);
1922 if (ret)
1923 goto failed;
1924
1925 ret = pcmcia_enable_device(link);
1926 if (ret)
1927 goto failed;
1928
1929 dev->irq = link->irq;
1930 dev->base_addr = link->resource[0]->start;
1931 SET_NETDEV_DEV(dev, &link->dev);
1932 if (register_netdev(dev)) {
1933 printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
1934 goto failed;
1935 }
1936
1937 this = netdev_priv(dev);
1938
1939 this->base_addr = dev->base_addr;
1940
1941 if (!wl3501_get_flash_mac_addr(this)) {
1942 printk(KERN_WARNING "%s: Can't read MAC addr in flash ROM?\n",
1943 dev->name);
1944 unregister_netdev(dev);
1945 goto failed;
1946 }
1947
1948 eth_hw_addr_set(dev, this->mac_addr);
1949
1950
1951 printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, "
1952 "MAC addr in flash ROM:%pM\n",
1953 dev->name, this->base_addr, (int)dev->irq,
1954 dev->dev_addr);
1955
1956
1957
1958 this->net_type = IW_MODE_INFRA;
1959 this->bss_cnt = 0;
1960 this->join_sta_bss = 0;
1961 this->adhoc_times = 0;
1962 iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID, &this->essid.el,
1963 "ANY", 3);
1964 this->card_name[0] = '\0';
1965 this->firmware_date[0] = '\0';
1966 this->rssi = 255;
1967 this->chan = iw_default_channel(this->reg_domain);
1968 strlcpy(this->nick, "Planet WL3501", sizeof(this->nick));
1969 spin_lock_init(&this->lock);
1970 init_waitqueue_head(&this->wait);
1971 netif_start_queue(dev);
1972 return 0;
1973
1974 failed:
1975 wl3501_release(link);
1976 return -ENODEV;
1977 }
1978
1979 static void wl3501_release(struct pcmcia_device *link)
1980 {
1981 pcmcia_disable_device(link);
1982 }
1983
1984 static int wl3501_suspend(struct pcmcia_device *link)
1985 {
1986 struct net_device *dev = link->priv;
1987
1988 wl3501_pwr_mgmt(netdev_priv(dev), WL3501_SUSPEND);
1989 if (link->open)
1990 netif_device_detach(dev);
1991
1992 return 0;
1993 }
1994
1995 static int wl3501_resume(struct pcmcia_device *link)
1996 {
1997 struct net_device *dev = link->priv;
1998
1999 wl3501_pwr_mgmt(netdev_priv(dev), WL3501_RESUME);
2000 if (link->open) {
2001 wl3501_reset(dev);
2002 netif_device_attach(dev);
2003 }
2004
2005 return 0;
2006 }
2007
2008
2009 static const struct pcmcia_device_id wl3501_ids[] = {
2010 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),
2011 PCMCIA_DEVICE_NULL
2012 };
2013 MODULE_DEVICE_TABLE(pcmcia, wl3501_ids);
2014
2015 static struct pcmcia_driver wl3501_driver = {
2016 .owner = THIS_MODULE,
2017 .name = "wl3501_cs",
2018 .probe = wl3501_probe,
2019 .remove = wl3501_detach,
2020 .id_table = wl3501_ids,
2021 .suspend = wl3501_suspend,
2022 .resume = wl3501_resume,
2023 };
2024 module_pcmcia_driver(wl3501_driver);
2025
2026 MODULE_AUTHOR("Fox Chen <mhchen@golf.ccl.itri.org.tw>, "
2027 "Arnaldo Carvalho de Melo <acme@conectiva.com.br>,"
2028 "Gustavo Niemeyer <niemeyer@conectiva.com>");
2029 MODULE_DESCRIPTION("Planet wl3501 wireless driver");
2030 MODULE_LICENSE("GPL");