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