Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.32 921 lines 24 kB view raw
1/* 2 * Copyright 2008 Pavel Machek <pavel@suse.cz> 3 * 4 * Distribute under GPLv2. 5 * 6 * The original driver was written by: 7 * Jeff Lee <YY_Lee@issc.com.tw> 8 * 9 * and was adapted to the 2.6 kernel by: 10 * Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar> 11 */ 12#include <net/mac80211.h> 13#include <linux/usb.h> 14 15#include "core.h" 16#include "mds_f.h" 17#include "mlmetxrx_f.h" 18#include "mto.h" 19#include "wbhal_f.h" 20#include "wblinux_f.h" 21 22MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); 23MODULE_LICENSE("GPL"); 24MODULE_VERSION("0.1"); 25 26static struct usb_device_id wb35_table[] __devinitdata = { 27 { USB_DEVICE(0x0416, 0x0035) }, 28 { USB_DEVICE(0x18E8, 0x6201) }, 29 { USB_DEVICE(0x18E8, 0x6206) }, 30 { USB_DEVICE(0x18E8, 0x6217) }, 31 { USB_DEVICE(0x18E8, 0x6230) }, 32 { USB_DEVICE(0x18E8, 0x6233) }, 33 { USB_DEVICE(0x1131, 0x2035) }, 34 { 0, } 35}; 36 37MODULE_DEVICE_TABLE(usb, wb35_table); 38 39static struct ieee80211_rate wbsoft_rates[] = { 40 { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 41}; 42 43static struct ieee80211_channel wbsoft_channels[] = { 44 { .center_freq = 2412 }, 45}; 46 47static struct ieee80211_supported_band wbsoft_band_2GHz = { 48 .channels = wbsoft_channels, 49 .n_channels = ARRAY_SIZE(wbsoft_channels), 50 .bitrates = wbsoft_rates, 51 .n_bitrates = ARRAY_SIZE(wbsoft_rates), 52}; 53 54static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period) 55{ 56 u32 tmp; 57 58 if (pHwData->SurpriseRemove) 59 return; 60 61 pHwData->BeaconPeriod = beacon_period; 62 tmp = pHwData->BeaconPeriod << 16; 63 tmp |= pHwData->ProbeDelay; 64 Wb35Reg_Write(pHwData, 0x0848, tmp); 65} 66 67static int wbsoft_add_interface(struct ieee80211_hw *dev, 68 struct ieee80211_if_init_conf *conf) 69{ 70 struct wbsoft_priv *priv = dev->priv; 71 72 hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int); 73 74 return 0; 75} 76 77static void wbsoft_remove_interface(struct ieee80211_hw *dev, 78 struct ieee80211_if_init_conf *conf) 79{ 80 printk("wbsoft_remove interface called\n"); 81} 82 83static void wbsoft_stop(struct ieee80211_hw *hw) 84{ 85 printk(KERN_INFO "%s called\n", __func__); 86} 87 88static int wbsoft_get_stats(struct ieee80211_hw *hw, 89 struct ieee80211_low_level_stats *stats) 90{ 91 printk(KERN_INFO "%s called\n", __func__); 92 return 0; 93} 94 95static int wbsoft_get_tx_stats(struct ieee80211_hw *hw, 96 struct ieee80211_tx_queue_stats *stats) 97{ 98 printk(KERN_INFO "%s called\n", __func__); 99 return 0; 100} 101 102static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count, 103 struct dev_addr_list *mc_list) 104{ 105 return mc_count; 106} 107 108static void wbsoft_configure_filter(struct ieee80211_hw *dev, 109 unsigned int changed_flags, 110 unsigned int *total_flags, 111 u64 multicast) 112{ 113 unsigned int new_flags; 114 115 new_flags = 0; 116 117 if (*total_flags & FIF_PROMISC_IN_BSS) 118 new_flags |= FIF_PROMISC_IN_BSS; 119 else if ((*total_flags & FIF_ALLMULTI) || (multicast > 32)) 120 new_flags |= FIF_ALLMULTI; 121 122 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; 123 124 *total_flags = new_flags; 125} 126 127static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb) 128{ 129 struct wbsoft_priv *priv = dev->priv; 130 131 MLMESendFrame(priv, skb->data, skb->len, FRAME_TYPE_802_11_MANAGEMENT); 132 133 return NETDEV_TX_OK; 134} 135 136static int wbsoft_start(struct ieee80211_hw *dev) 137{ 138 struct wbsoft_priv *priv = dev->priv; 139 140 priv->enabled = true; 141 142 return 0; 143} 144 145static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off) 146{ 147 struct wb35_reg *reg = &pHwData->reg; 148 149 if (pHwData->SurpriseRemove) 150 return; 151 152 if (radio_off) //disable Baseband receive off 153 { 154 pHwData->CurrentRadioSw = 1; // off 155 reg->M24_MacControl &= 0xffffffbf; 156 } else { 157 pHwData->CurrentRadioSw = 0; // on 158 reg->M24_MacControl |= 0x00000040; 159 } 160 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl); 161} 162 163static void 164hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel) 165{ 166 struct wb35_reg *reg = &pHwData->reg; 167 168 if (pHwData->SurpriseRemove) 169 return; 170 171 printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo); 172 173 RFSynthesizer_SwitchingChannel(pHwData, channel); // Switch channel 174 pHwData->Channel = channel.ChanNo; 175 pHwData->band = channel.band; 176#ifdef _PE_STATE_DUMP_ 177 printk("Set channel is %d, band =%d\n", pHwData->Channel, 178 pHwData->band); 179#endif 180 reg->M28_MacControl &= ~0xff; // Clean channel information field 181 reg->M28_MacControl |= channel.ChanNo; 182 Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl, 183 (s8 *) & channel, sizeof(ChanInfo)); 184} 185 186static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel) 187{ 188 hal_set_current_channel_ex(pHwData, channel); 189} 190 191static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable) 192{ 193 struct wb35_reg *reg = &pHwData->reg; 194 195 if (pHwData->SurpriseRemove) 196 return; 197 198 reg->M00_MacControl &= ~0x02000000; //The HW value 199 200 if (enable) 201 reg->M00_MacControl |= 0x02000000; //The HW value 202 203 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); 204} 205 206//for wep key error detection, we need to accept broadcast packets to be received temporary. 207static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable) 208{ 209 struct wb35_reg *reg = &pHwData->reg; 210 211 if (pHwData->SurpriseRemove) 212 return; 213 if (enable) { 214 reg->M00_MacControl |= 0x00400000; 215 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); 216 } else { 217 reg->M00_MacControl &= ~0x00400000; 218 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); 219 } 220} 221 222static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable) 223{ 224 struct wb35_reg *reg = &pHwData->reg; 225 226 if (pHwData->SurpriseRemove) 227 return; 228 229 reg->M00_MacControl &= ~0x01000000; //The HW value 230 if (enable) 231 reg->M00_MacControl |= 0x01000000; //The HW value 232 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); 233} 234 235static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable) 236{ 237 struct wb35_reg *reg = &pHwData->reg; 238 239 if (pHwData->SurpriseRemove) 240 return; 241 242 // 20040108 debug 243 if (!enable) //Due to SME and MLME are not suitable for 35 244 return; 245 246 reg->M00_MacControl &= ~0x04000000; //The HW value 247 if (enable) 248 reg->M00_MacControl |= 0x04000000; //The HW value 249 250 Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); 251} 252 253static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) 254{ 255 struct wbsoft_priv *priv = dev->priv; 256 ChanInfo ch; 257 258 printk("wbsoft_config called\n"); 259 260 /* Should use channel_num, or something, as that is already pre-translated */ 261 ch.band = 1; 262 ch.ChanNo = 1; 263 264 hal_set_current_channel(&priv->sHwData, ch); 265 hal_set_accept_broadcast(&priv->sHwData, 1); 266 hal_set_accept_promiscuous(&priv->sHwData, 1); 267 hal_set_accept_multicast(&priv->sHwData, 1); 268 hal_set_accept_beacon(&priv->sHwData, 1); 269 hal_set_radio_mode(&priv->sHwData, 0); 270 271 return 0; 272} 273 274static u64 wbsoft_get_tsf(struct ieee80211_hw *dev) 275{ 276 printk("wbsoft_get_tsf called\n"); 277 return 0; 278} 279 280static const struct ieee80211_ops wbsoft_ops = { 281 .tx = wbsoft_tx, 282 .start = wbsoft_start, 283 .stop = wbsoft_stop, 284 .add_interface = wbsoft_add_interface, 285 .remove_interface = wbsoft_remove_interface, 286 .config = wbsoft_config, 287 .prepare_multicast = wbsoft_prepare_multicast, 288 .configure_filter = wbsoft_configure_filter, 289 .get_stats = wbsoft_get_stats, 290 .get_tx_stats = wbsoft_get_tx_stats, 291 .get_tsf = wbsoft_get_tsf, 292}; 293 294static void 295hal_set_ethernet_address(struct hw_data *pHwData, u8 * current_address) 296{ 297 u32 ltmp[2]; 298 299 if (pHwData->SurpriseRemove) 300 return; 301 302 memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN); 303 304 ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress); 305 ltmp[1] = 306 cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff; 307 308 Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT); 309} 310 311static void 312hal_get_permanent_address(struct hw_data *pHwData, u8 * pethernet_address) 313{ 314 if (pHwData->SurpriseRemove) 315 return; 316 317 memcpy(pethernet_address, pHwData->PermanentMacAddress, 6); 318} 319 320static void hal_stop(struct hw_data *pHwData) 321{ 322 struct wb35_reg *reg = &pHwData->reg; 323 324 pHwData->Wb35Rx.rx_halt = 1; 325 Wb35Rx_stop(pHwData); 326 327 pHwData->Wb35Tx.tx_halt = 1; 328 Wb35Tx_stop(pHwData); 329 330 reg->D00_DmaControl &= ~0xc0000000; //Tx Off, Rx Off 331 Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl); 332} 333 334static unsigned char hal_idle(struct hw_data *pHwData) 335{ 336 struct wb35_reg *reg = &pHwData->reg; 337 struct wb_usb *pWbUsb = &pHwData->WbUsb; 338 339 if (!pHwData->SurpriseRemove 340 && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP)) 341 return false; 342 343 return true; 344} 345 346u8 hal_get_antenna_number(struct hw_data *pHwData) 347{ 348 struct wb35_reg *reg = &pHwData->reg; 349 350 if ((reg->BB2C & BIT(11)) == 0) 351 return 0; 352 else 353 return 1; 354} 355 356/* 0 : radio on; 1: radio off */ 357static u8 hal_get_hw_radio_off(struct hw_data * pHwData) 358{ 359 struct wb35_reg *reg = &pHwData->reg; 360 361 if (pHwData->SurpriseRemove) 362 return 1; 363 364 //read the bit16 of register U1B0 365 Wb35Reg_Read(pHwData, 0x3b0, &reg->U1B0); 366 if ((reg->U1B0 & 0x00010000)) { 367 pHwData->CurrentRadioHw = 1; 368 return 1; 369 } else { 370 pHwData->CurrentRadioHw = 0; 371 return 0; 372 } 373} 374 375static u8 LED_GRAY[20] = { 376 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2 377}; 378 379static u8 LED_GRAY2[30] = { 380 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 381 0, 15, 14, 13, 12, 11, 10, 9, 8 382}; 383 384static void hal_led_control(unsigned long data) 385{ 386 struct wbsoft_priv *adapter = (struct wbsoft_priv *)data; 387 struct hw_data *pHwData = &adapter->sHwData; 388 struct wb35_reg *reg = &pHwData->reg; 389 u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT; 390 u32 TimeInterval = 500, ltmp, ltmp2; 391 ltmp = 0; 392 393 if (pHwData->SurpriseRemove) 394 return; 395 396 if (pHwData->LED_control) { 397 ltmp2 = pHwData->LED_control & 0xff; 398 if (ltmp2 == 5) // 5 is WPS mode 399 { 400 TimeInterval = 100; 401 ltmp2 = (pHwData->LED_control >> 8) & 0xff; 402 switch (ltmp2) { 403 case 1: // [0.2 On][0.1 Off]... 404 pHwData->LED_Blinking %= 3; 405 ltmp = 0x1010; // Led 1 & 0 Green and Red 406 if (pHwData->LED_Blinking == 2) // Turn off 407 ltmp = 0; 408 break; 409 case 2: // [0.1 On][0.1 Off]... 410 pHwData->LED_Blinking %= 2; 411 ltmp = 0x0010; // Led 0 red color 412 if (pHwData->LED_Blinking) // Turn off 413 ltmp = 0; 414 break; 415 case 3: // [0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.5 Off]... 416 pHwData->LED_Blinking %= 15; 417 ltmp = 0x0010; // Led 0 red color 418 if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2)) // Turn off 0.6 sec 419 ltmp = 0; 420 break; 421 case 4: // [300 On][ off ] 422 ltmp = 0x1000; // Led 1 Green color 423 if (pHwData->LED_Blinking >= 3000) 424 ltmp = 0; // led maybe on after 300sec * 32bit counter overlap. 425 break; 426 } 427 pHwData->LED_Blinking++; 428 429 reg->U1BC_LEDConfigure = ltmp; 430 if (LEDSet != 7) // Only 111 mode has 2 LEDs on PCB. 431 { 432 reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; // Copy LED result to each LED control register 433 reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8; 434 } 435 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); 436 } 437 } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) // If radio off 438 { 439 if (reg->U1BC_LEDConfigure & 0x1010) { 440 reg->U1BC_LEDConfigure &= ~0x1010; 441 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); 442 } 443 } else { 444 switch (LEDSet) { 445 case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing 446 if (!pHwData->LED_LinkOn) // Blink only if not Link On 447 { 448 // Blinking if scanning is on progress 449 if (pHwData->LED_Scanning) { 450 if (pHwData->LED_Blinking == 0) { 451 reg->U1BC_LEDConfigure |= 0x10; 452 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On 453 pHwData->LED_Blinking = 1; 454 TimeInterval = 300; 455 } else { 456 reg->U1BC_LEDConfigure &= ~0x10; 457 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off 458 pHwData->LED_Blinking = 0; 459 TimeInterval = 300; 460 } 461 } else { 462 //Turn Off LED_0 463 if (reg->U1BC_LEDConfigure & 0x10) { 464 reg->U1BC_LEDConfigure &= ~0x10; 465 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off 466 } 467 } 468 } else { 469 // Turn On LED_0 470 if ((reg->U1BC_LEDConfigure & 0x10) == 0) { 471 reg->U1BC_LEDConfigure |= 0x10; 472 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off 473 } 474 } 475 break; 476 477 case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing 478 if (!pHwData->LED_LinkOn) // Blink only if not Link On 479 { 480 // Blinking if scanning is on progress 481 if (pHwData->LED_Scanning) { 482 if (pHwData->LED_Blinking == 0) { 483 reg->U1BC_LEDConfigure &= ~0xf; 484 reg->U1BC_LEDConfigure |= 0x10; 485 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On 486 pHwData->LED_Blinking = 1; 487 TimeInterval = 300; 488 } else { 489 reg->U1BC_LEDConfigure &= ~0x1f; 490 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off 491 pHwData->LED_Blinking = 0; 492 TimeInterval = 300; 493 } 494 } else { 495 // 20060901 Gray blinking if in disconnect state and not scanning 496 ltmp = reg->U1BC_LEDConfigure; 497 reg->U1BC_LEDConfigure &= ~0x1f; 498 if (LED_GRAY2[(pHwData->LED_Blinking % 30)]) { 499 reg->U1BC_LEDConfigure |= 0x10; 500 reg->U1BC_LEDConfigure |= 501 LED_GRAY2[(pHwData->LED_Blinking % 30)]; 502 } 503 pHwData->LED_Blinking++; 504 if (reg->U1BC_LEDConfigure != ltmp) 505 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off 506 TimeInterval = 100; 507 } 508 } else { 509 // Turn On LED_0 510 if ((reg->U1BC_LEDConfigure & 0x10) == 0) { 511 reg->U1BC_LEDConfigure |= 0x10; 512 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off 513 } 514 } 515 break; 516 517 case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing 518 if (!pHwData->LED_LinkOn) // Blink only if not Link On 519 { 520 // Blinking if scanning is on progress 521 if (pHwData->LED_Scanning) { 522 if (pHwData->LED_Blinking == 0) { 523 reg->U1BC_LEDConfigure |= 524 0x1000; 525 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On 526 pHwData->LED_Blinking = 1; 527 TimeInterval = 300; 528 } else { 529 reg->U1BC_LEDConfigure &= 530 ~0x1000; 531 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off 532 pHwData->LED_Blinking = 0; 533 TimeInterval = 300; 534 } 535 } else { 536 //Turn Off LED_1 537 if (reg->U1BC_LEDConfigure & 0x1000) { 538 reg->U1BC_LEDConfigure &= 539 ~0x1000; 540 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off 541 } 542 } 543 } else { 544 // Is transmitting/receiving ?? 545 if ((adapter->RxByteCount != 546 pHwData->RxByteCountLast) 547 || (adapter->TxByteCount != 548 pHwData->TxByteCountLast)) { 549 if ((reg->U1BC_LEDConfigure & 0x3000) != 550 0x3000) { 551 reg->U1BC_LEDConfigure |= 552 0x3000; 553 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On 554 } 555 // Update variable 556 pHwData->RxByteCountLast = 557 adapter->RxByteCount; 558 pHwData->TxByteCountLast = 559 adapter->TxByteCount; 560 TimeInterval = 200; 561 } else { 562 // Turn On LED_1 and blinking if transmitting/receiving 563 if ((reg->U1BC_LEDConfigure & 0x3000) != 564 0x1000) { 565 reg->U1BC_LEDConfigure &= 566 ~0x3000; 567 reg->U1BC_LEDConfigure |= 568 0x1000; 569 Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On 570 } 571 } 572 } 573 break; 574 575 default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active 576 if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) { 577 reg->U1BC_LEDConfigure |= 0x3000; // LED_1 is always on and event enable 578 Wb35Reg_Write(pHwData, 0x03bc, 579 reg->U1BC_LEDConfigure); 580 } 581 582 if (pHwData->LED_Blinking) { 583 // Gray blinking 584 reg->U1BC_LEDConfigure &= ~0x0f; 585 reg->U1BC_LEDConfigure |= 0x10; 586 reg->U1BC_LEDConfigure |= 587 LED_GRAY[(pHwData->LED_Blinking - 1) % 20]; 588 Wb35Reg_Write(pHwData, 0x03bc, 589 reg->U1BC_LEDConfigure); 590 591 pHwData->LED_Blinking += 2; 592 if (pHwData->LED_Blinking < 40) 593 TimeInterval = 100; 594 else { 595 pHwData->LED_Blinking = 0; // Stop blinking 596 reg->U1BC_LEDConfigure &= ~0x0f; 597 Wb35Reg_Write(pHwData, 0x03bc, 598 reg->U1BC_LEDConfigure); 599 } 600 break; 601 } 602 603 if (pHwData->LED_LinkOn) { 604 if (!(reg->U1BC_LEDConfigure & 0x10)) // Check the LED_0 605 { 606 //Try to turn ON LED_0 after gray blinking 607 reg->U1BC_LEDConfigure |= 0x10; 608 pHwData->LED_Blinking = 1; //Start blinking 609 TimeInterval = 50; 610 } 611 } else { 612 if (reg->U1BC_LEDConfigure & 0x10) // Check the LED_0 613 { 614 reg->U1BC_LEDConfigure &= ~0x10; 615 Wb35Reg_Write(pHwData, 0x03bc, 616 reg->U1BC_LEDConfigure); 617 } 618 } 619 break; 620 } 621 622 //20060828.1 Active send null packet to avoid AP disconnect 623 if (pHwData->LED_LinkOn) { 624 pHwData->NullPacketCount += TimeInterval; 625 if (pHwData->NullPacketCount >= 626 DEFAULT_NULL_PACKET_COUNT) { 627 pHwData->NullPacketCount = 0; 628 } 629 } 630 } 631 632 pHwData->time_count += TimeInterval; 633 Wb35Tx_CurrentTime(adapter, pHwData->time_count); // 20060928 add 634 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval); 635 add_timer(&pHwData->LEDTimer); 636} 637 638static int hal_init_hardware(struct ieee80211_hw *hw) 639{ 640 struct wbsoft_priv *priv = hw->priv; 641 struct hw_data *pHwData = &priv->sHwData; 642 u16 SoftwareSet; 643 644 pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME; 645 pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; 646 647 if (!Wb35Reg_initial(pHwData)) 648 goto error_reg_destroy; 649 650 if (!Wb35Tx_initial(pHwData)) 651 goto error_tx_destroy; 652 653 if (!Wb35Rx_initial(pHwData)) 654 goto error_rx_destroy; 655 656 init_timer(&pHwData->LEDTimer); 657 pHwData->LEDTimer.function = hal_led_control; 658 pHwData->LEDTimer.data = (unsigned long)priv; 659 pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000); 660 add_timer(&pHwData->LEDTimer); 661 662 SoftwareSet = hal_software_set(pHwData); 663 664#ifdef Vendor2 665 // Try to make sure the EEPROM contain 666 SoftwareSet >>= 8; 667 if (SoftwareSet != 0x82) 668 return false; 669#endif 670 671 Wb35Rx_start(hw); 672 Wb35Tx_EP2VM_start(priv); 673 674 return 0; 675 676error_rx_destroy: 677 Wb35Rx_destroy(pHwData); 678error_tx_destroy: 679 Wb35Tx_destroy(pHwData); 680error_reg_destroy: 681 Wb35Reg_destroy(pHwData); 682 683 pHwData->SurpriseRemove = 1; 684 return -EINVAL; 685} 686 687static int wb35_hw_init(struct ieee80211_hw *hw) 688{ 689 struct wbsoft_priv *priv = hw->priv; 690 struct hw_data *pHwData = &priv->sHwData; 691 u8 EEPROM_region; 692 u8 HwRadioOff; 693 u8 *pMacAddr2; 694 u8 *pMacAddr; 695 int err; 696 697 pHwData->phy_type = RF_DECIDE_BY_INF; 698 699 priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold; 700 priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; 701 702 priv->sLocalPara.region_INF = REGION_AUTO; 703 priv->sLocalPara.TxRateMode = RATE_AUTO; 704 priv->sLocalPara.bMacOperationMode = MODE_802_11_BG; 705 priv->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE; 706 priv->sLocalPara.bPreambleMode = AUTO_MODE; 707 priv->sLocalPara.bWepKeyError = false; 708 priv->sLocalPara.bToSelfPacketReceived = false; 709 priv->sLocalPara.WepKeyDetectTimerCount = 2 * 100; /* 2 seconds */ 710 711 priv->sLocalPara.RadioOffStatus.boSwRadioOff = false; 712 713 err = hal_init_hardware(hw); 714 if (err) 715 goto error; 716 717 EEPROM_region = hal_get_region_from_EEPROM(pHwData); 718 if (EEPROM_region != REGION_AUTO) 719 priv->sLocalPara.region = EEPROM_region; 720 else { 721 if (priv->sLocalPara.region_INF != REGION_AUTO) 722 priv->sLocalPara.region = priv->sLocalPara.region_INF; 723 else 724 priv->sLocalPara.region = REGION_USA; /* default setting */ 725 } 726 727 Mds_initial(priv); 728 729 /* 730 * If no user-defined address in the registry, use the addresss 731 * "burned" on the NIC instead. 732 */ 733 pMacAddr = priv->sLocalPara.ThisMacAddress; 734 pMacAddr2 = priv->sLocalPara.PermanentAddress; 735 736 /* Reading ethernet address from EEPROM */ 737 hal_get_permanent_address(pHwData, priv->sLocalPara.PermanentAddress); 738 if (memcmp(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) == 0) 739 memcpy(pMacAddr, pMacAddr2, MAC_ADDR_LENGTH); 740 else { 741 /* Set the user define MAC address */ 742 hal_set_ethernet_address(pHwData, 743 priv->sLocalPara.ThisMacAddress); 744 } 745 746 priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData); 747#ifdef _PE_STATE_DUMP_ 748 printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo); 749#endif 750 hal_get_hw_radio_off(pHwData); 751 752 /* Waiting for HAL setting OK */ 753 while (!hal_idle(pHwData)) 754 msleep(10); 755 756 MTO_Init(priv); 757 758 HwRadioOff = hal_get_hw_radio_off(pHwData); 759 priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff; 760 761 hal_set_radio_mode(pHwData, 762 (unsigned char)(priv->sLocalPara.RadioOffStatus. 763 boSwRadioOff 764 || priv->sLocalPara.RadioOffStatus. 765 boHwRadioOff)); 766 767 /* Notify hal that the driver is ready now. */ 768 hal_driver_init_OK(pHwData) = 1; 769 770error: 771 return err; 772} 773 774static int wb35_probe(struct usb_interface *intf, 775 const struct usb_device_id *id_table) 776{ 777 struct usb_device *udev = interface_to_usbdev(intf); 778 struct usb_endpoint_descriptor *endpoint; 779 struct usb_host_interface *interface; 780 struct ieee80211_hw *dev; 781 struct wbsoft_priv *priv; 782 struct wb_usb *pWbUsb; 783 int nr, err; 784 u32 ltmp; 785 786 usb_get_dev(udev); 787 788 /* Check the device if it already be opened */ 789 nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 790 0x01, 791 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 792 0x0, 0x400, &ltmp, 4, HZ * 100); 793 if (nr < 0) { 794 err = nr; 795 goto error; 796 } 797 798 /* Is already initialized? */ 799 ltmp = cpu_to_le32(ltmp); 800 if (ltmp) { 801 err = -EBUSY; 802 goto error; 803 } 804 805 dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops); 806 if (!dev) { 807 err = -ENOMEM; 808 goto error; 809 } 810 811 priv = dev->priv; 812 813 spin_lock_init(&priv->SpinLock); 814 815 pWbUsb = &priv->sHwData.WbUsb; 816 pWbUsb->udev = udev; 817 818 interface = intf->cur_altsetting; 819 endpoint = &interface->endpoint[0].desc; 820 821 if (endpoint[2].wMaxPacketSize == 512) { 822 printk("[w35und] Working on USB 2.0\n"); 823 pWbUsb->IsUsb20 = 1; 824 } 825 826 err = wb35_hw_init(dev); 827 if (err) 828 goto error_free_hw; 829 830 SET_IEEE80211_DEV(dev, &udev->dev); 831 { 832 struct hw_data *pHwData = &priv->sHwData; 833 unsigned char dev_addr[MAX_ADDR_LEN]; 834 hal_get_permanent_address(pHwData, dev_addr); 835 SET_IEEE80211_PERM_ADDR(dev, dev_addr); 836 } 837 838 dev->extra_tx_headroom = 12; /* FIXME */ 839 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; 840 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 841 842 dev->channel_change_time = 1000; 843 dev->max_signal = 100; 844 dev->queues = 1; 845 846 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz; 847 848 err = ieee80211_register_hw(dev); 849 if (err) 850 goto error_free_hw; 851 852 usb_set_intfdata(intf, dev); 853 854 return 0; 855 856error_free_hw: 857 ieee80211_free_hw(dev); 858error: 859 usb_put_dev(udev); 860 return err; 861} 862 863static void hal_halt(struct hw_data *pHwData) 864{ 865 del_timer_sync(&pHwData->LEDTimer); 866 /* XXX: Wait for Timer DPC exit. */ 867 msleep(100); 868 Wb35Rx_destroy(pHwData); 869 Wb35Tx_destroy(pHwData); 870 Wb35Reg_destroy(pHwData); 871} 872 873static void wb35_hw_halt(struct wbsoft_priv *adapter) 874{ 875 Mds_Destroy(adapter); 876 877 /* Turn off Rx and Tx hardware ability */ 878 hal_stop(&adapter->sHwData); 879#ifdef _PE_USB_INI_DUMP_ 880 printk("[w35und] Hal_stop O.K.\n"); 881#endif 882 /* Waiting Irp completed */ 883 msleep(100); 884 885 hal_halt(&adapter->sHwData); 886} 887 888static void wb35_disconnect(struct usb_interface *intf) 889{ 890 struct ieee80211_hw *hw = usb_get_intfdata(intf); 891 struct wbsoft_priv *priv = hw->priv; 892 893 wb35_hw_halt(priv); 894 895 ieee80211_stop_queues(hw); 896 ieee80211_unregister_hw(hw); 897 ieee80211_free_hw(hw); 898 899 usb_set_intfdata(intf, NULL); 900 usb_put_dev(interface_to_usbdev(intf)); 901} 902 903static struct usb_driver wb35_driver = { 904 .name = "w35und", 905 .id_table = wb35_table, 906 .probe = wb35_probe, 907 .disconnect = wb35_disconnect, 908}; 909 910static int __init wb35_init(void) 911{ 912 return usb_register(&wb35_driver); 913} 914 915static void __exit wb35_exit(void) 916{ 917 usb_deregister(&wb35_driver); 918} 919 920module_init(wb35_init); 921module_exit(wb35_exit);