diff options
Diffstat (limited to 'drivers/staging/winbond')
-rw-r--r-- | drivers/staging/winbond/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/winbond/mds.c | 2 | ||||
-rw-r--r-- | drivers/staging/winbond/mto.c | 2 | ||||
-rw-r--r-- | drivers/staging/winbond/phy_calibration.c | 19 | ||||
-rw-r--r-- | drivers/staging/winbond/wbhal.c | 568 | ||||
-rw-r--r-- | drivers/staging/winbond/wbhal_f.h | 21 | ||||
-rw-r--r-- | drivers/staging/winbond/wbhal_s.h | 1 | ||||
-rw-r--r-- | drivers/staging/winbond/wbusb.c | 785 |
8 files changed, 648 insertions, 751 deletions
diff --git a/drivers/staging/winbond/Makefile b/drivers/staging/winbond/Makefile index b49c9730edd..fb2b7d432b4 100644 --- a/drivers/staging/winbond/Makefile +++ b/drivers/staging/winbond/Makefile @@ -7,7 +7,6 @@ w35und-objs := \ wb35reg.o \ wb35rx.o \ wb35tx.o \ - wbhal.o \ wbusb.o \ diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index c7af09257e6..59d6d67a9f7 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -432,7 +432,7 @@ Mds_Tx(struct wbsoft_priv * adapter) return; //Only one thread can be run here - if (!atomic_inc_return(&pMds->TxThreadCount) == 1) + if (atomic_inc_return(&pMds->TxThreadCount) != 1) goto cleanup; // Start to fill the data diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c index 94a060bcc62..7deb5c76976 100644 --- a/drivers/staging/winbond/mto.c +++ b/drivers/staging/winbond/mto.c @@ -175,7 +175,7 @@ void MTO_Init(struct wbsoft_priv *adapter) } else //follow the setting from EEPROM MTOPARA_TXPOWER_INDEX() = MTO_TXPOWER_FROM_EEPROM; - hal_set_rf_power(MTO_HAL(), (u8)MTOPARA_TXPOWER_INDEX()); + RFSynthesizer_SetPowerIndex(MTO_HAL(), (u8)MTOPARA_TXPOWER_INDEX()); //------------------------------------------------ // For RSSI turning 20060808.4 Cancel load from EEPROM diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c index af8c01e313b..8c56962ab80 100644 --- a/drivers/staging/winbond/phy_calibration.c +++ b/drivers/staging/winbond/phy_calibration.c @@ -340,6 +340,25 @@ void _sin_cos(s32 angle, s32 *sin, s32 *cos) } } +static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 * pValue) +{ + if (number < 0x1000) + number += 0x1000; + return Wb35Reg_ReadSync(pHwData, number, pValue); +} +#define hw_get_dxx_reg( _A, _B, _C ) hal_get_dxx_reg( _A, _B, (u32 *)_C ) + +static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value) +{ + unsigned char ret; + + if (number < 0x1000) + number += 0x1000; + ret = Wb35Reg_WriteSync(pHwData, number, value); + return ret; +} +#define hw_set_dxx_reg( _A, _B, _C ) hal_set_dxx_reg( _A, _B, (u32)_C ) + void _reset_rx_cal(struct hw_data *phw_data) { diff --git a/drivers/staging/winbond/wbhal.c b/drivers/staging/winbond/wbhal.c deleted file mode 100644 index c985ad06523..00000000000 --- a/drivers/staging/winbond/wbhal.c +++ /dev/null @@ -1,568 +0,0 @@ -#include "sysdef.h" -#include "wbhal_f.h" -#include "wblinux_f.h" - -void hal_set_ethernet_address( struct hw_data * pHwData, u8 *current_address ) -{ - u32 ltmp[2]; - - if( pHwData->SurpriseRemove ) return; - - memcpy( pHwData->CurrentMacAddress, current_address, ETH_ALEN ); - - ltmp[0]= cpu_to_le32( *(u32 *)pHwData->CurrentMacAddress ); - ltmp[1]= cpu_to_le32( *(u32 *)(pHwData->CurrentMacAddress + 4) ) & 0xffff; - - Wb35Reg_BurstWrite( pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT ); -} - -void hal_get_permanent_address( struct hw_data * pHwData, u8 *pethernet_address ) -{ - if( pHwData->SurpriseRemove ) return; - - memcpy( pethernet_address, pHwData->PermanentMacAddress, 6 ); -} - -static void hal_led_control(unsigned long data) -{ - struct wbsoft_priv *adapter = (struct wbsoft_priv *) data; - struct hw_data * pHwData = &adapter->sHwData; - struct wb35_reg *reg = &pHwData->reg; - u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT; - u8 LEDgray[20] = { 0,3,4,6,8,10,11,12,13,14,15,14,13,12,11,10,8,6,4,2 }; - u8 LEDgray2[30] = { 7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,15,14,13,12,11,10,9,8 }; - u32 TimeInterval = 500, ltmp, ltmp2; - ltmp=0; - - if( pHwData->SurpriseRemove ) return; - - if( pHwData->LED_control ) { - ltmp2 = pHwData->LED_control & 0xff; - if( ltmp2 == 5 ) // 5 is WPS mode - { - TimeInterval = 100; - ltmp2 = (pHwData->LED_control>>8) & 0xff; - switch( ltmp2 ) - { - case 1: // [0.2 On][0.1 Off]... - pHwData->LED_Blinking %= 3; - ltmp = 0x1010; // Led 1 & 0 Green and Red - if( pHwData->LED_Blinking == 2 ) // Turn off - ltmp = 0; - break; - case 2: // [0.1 On][0.1 Off]... - pHwData->LED_Blinking %= 2; - ltmp = 0x0010; // Led 0 red color - if( pHwData->LED_Blinking ) // Turn off - ltmp = 0; - break; - 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]... - pHwData->LED_Blinking %= 15; - ltmp = 0x0010; // Led 0 red color - if( (pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking%2) ) // Turn off 0.6 sec - ltmp = 0; - break; - case 4: // [300 On][ off ] - ltmp = 0x1000; // Led 1 Green color - if( pHwData->LED_Blinking >= 3000 ) - ltmp = 0; // led maybe on after 300sec * 32bit counter overlap. - break; - } - pHwData->LED_Blinking++; - - reg->U1BC_LEDConfigure = ltmp; - if( LEDSet != 7 ) // Only 111 mode has 2 LEDs on PCB. - { - reg->U1BC_LEDConfigure |= (ltmp &0xff)<<8; // Copy LED result to each LED control register - reg->U1BC_LEDConfigure |= (ltmp &0xff00)>>8; - } - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); - } - } - else if( pHwData->CurrentRadioSw || pHwData->CurrentRadioHw ) // If radio off - { - if( reg->U1BC_LEDConfigure & 0x1010 ) - { - reg->U1BC_LEDConfigure &= ~0x1010; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); - } - } - else - { - switch( LEDSet ) - { - case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing - if( !pHwData->LED_LinkOn ) // Blink only if not Link On - { - // Blinking if scanning is on progress - if( pHwData->LED_Scanning ) - { - if( pHwData->LED_Blinking == 0 ) - { - reg->U1BC_LEDConfigure |= 0x10; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_0 On - pHwData->LED_Blinking = 1; - TimeInterval = 300; - } - else - { - reg->U1BC_LEDConfigure &= ~0x10; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_0 Off - pHwData->LED_Blinking = 0; - TimeInterval = 300; - } - } - else - { - //Turn Off LED_0 - if( reg->U1BC_LEDConfigure & 0x10 ) - { - reg->U1BC_LEDConfigure &= ~0x10; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_0 Off - } - } - } - else - { - // Turn On LED_0 - if( (reg->U1BC_LEDConfigure & 0x10) == 0 ) - { - reg->U1BC_LEDConfigure |= 0x10; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_0 Off - } - } - break; - - case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing - if( !pHwData->LED_LinkOn ) // Blink only if not Link On - { - // Blinking if scanning is on progress - if( pHwData->LED_Scanning ) - { - if( pHwData->LED_Blinking == 0 ) - { - reg->U1BC_LEDConfigure &= ~0xf; - reg->U1BC_LEDConfigure |= 0x10; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_0 On - pHwData->LED_Blinking = 1; - TimeInterval = 300; - } - else - { - reg->U1BC_LEDConfigure &= ~0x1f; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_0 Off - pHwData->LED_Blinking = 0; - TimeInterval = 300; - } - } - else - { - // 20060901 Gray blinking if in disconnect state and not scanning - ltmp = reg->U1BC_LEDConfigure; - reg->U1BC_LEDConfigure &= ~0x1f; - if( LEDgray2[(pHwData->LED_Blinking%30)] ) - { - reg->U1BC_LEDConfigure |= 0x10; - reg->U1BC_LEDConfigure |= LEDgray2[ (pHwData->LED_Blinking%30) ]; - } - pHwData->LED_Blinking++; - if( reg->U1BC_LEDConfigure != ltmp ) - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_0 Off - TimeInterval = 100; - } - } - else - { - // Turn On LED_0 - if( (reg->U1BC_LEDConfigure & 0x10) == 0 ) - { - reg->U1BC_LEDConfigure |= 0x10; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_0 Off - } - } - break; - - case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing - if( !pHwData->LED_LinkOn ) // Blink only if not Link On - { - // Blinking if scanning is on progress - if( pHwData->LED_Scanning ) - { - if( pHwData->LED_Blinking == 0 ) - { - reg->U1BC_LEDConfigure |= 0x1000; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_1 On - pHwData->LED_Blinking = 1; - TimeInterval = 300; - } - else - { - reg->U1BC_LEDConfigure &= ~0x1000; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_1 Off - pHwData->LED_Blinking = 0; - TimeInterval = 300; - } - } - else - { - //Turn Off LED_1 - if( reg->U1BC_LEDConfigure & 0x1000 ) - { - reg->U1BC_LEDConfigure &= ~0x1000; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_1 Off - } - } - } - else - { - // Is transmitting/receiving ?? - if( (adapter->RxByteCount != pHwData->RxByteCountLast ) || - (adapter->TxByteCount != pHwData->TxByteCountLast ) ) - { - if( (reg->U1BC_LEDConfigure & 0x3000) != 0x3000 ) - { - reg->U1BC_LEDConfigure |= 0x3000; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_1 On - } - - // Update variable - pHwData->RxByteCountLast = adapter->RxByteCount; - pHwData->TxByteCountLast = adapter->TxByteCount; - TimeInterval = 200; - } - else - { - // Turn On LED_1 and blinking if transmitting/receiving - if( (reg->U1BC_LEDConfigure & 0x3000) != 0x1000 ) - { - reg->U1BC_LEDConfigure &= ~0x3000; - reg->U1BC_LEDConfigure |= 0x1000; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); // LED_1 On - } - } - } - break; - - default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active - if( (reg->U1BC_LEDConfigure & 0x3000) != 0x3000 ) - { - reg->U1BC_LEDConfigure |= 0x3000;// LED_1 is always on and event enable - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); - } - - if( pHwData->LED_Blinking ) - { - // Gray blinking - reg->U1BC_LEDConfigure &= ~0x0f; - reg->U1BC_LEDConfigure |= 0x10; - reg->U1BC_LEDConfigure |= LEDgray[ (pHwData->LED_Blinking-1)%20 ]; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); - - pHwData->LED_Blinking += 2; - if( pHwData->LED_Blinking < 40 ) - TimeInterval = 100; - else - { - pHwData->LED_Blinking = 0; // Stop blinking - reg->U1BC_LEDConfigure &= ~0x0f; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); - } - break; - } - - if( pHwData->LED_LinkOn ) - { - if( !(reg->U1BC_LEDConfigure & 0x10) ) // Check the LED_0 - { - //Try to turn ON LED_0 after gray blinking - reg->U1BC_LEDConfigure |= 0x10; - pHwData->LED_Blinking = 1; //Start blinking - TimeInterval = 50; - } - } - else - { - if( reg->U1BC_LEDConfigure & 0x10 ) // Check the LED_0 - { - reg->U1BC_LEDConfigure &= ~0x10; - Wb35Reg_Write( pHwData, 0x03bc, reg->U1BC_LEDConfigure ); - } - } - break; - } - - //20060828.1 Active send null packet to avoid AP disconnect - if( pHwData->LED_LinkOn ) - { - pHwData->NullPacketCount += TimeInterval; - if( pHwData->NullPacketCount >= DEFAULT_NULL_PACKET_COUNT ) - { - pHwData->NullPacketCount = 0; - } - } - } - - pHwData->time_count += TimeInterval; - Wb35Tx_CurrentTime(adapter, pHwData->time_count); // 20060928 add - pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval); - add_timer(&pHwData->LEDTimer); -} - -u8 hal_init_hardware(struct ieee80211_hw *hw) -{ - struct wbsoft_priv *priv = hw->priv; - struct hw_data * pHwData = &priv->sHwData; - u16 SoftwareSet; - - // Initial the variable - pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME; // Setting Rx maximum MSDU life time - pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; // Setting default fragment threshold - - pHwData->InitialResource = 1; - if( Wb35Reg_initial(pHwData)) { - pHwData->InitialResource = 2; - if (Wb35Tx_initial(pHwData)) { - pHwData->InitialResource = 3; - if (Wb35Rx_initial(pHwData)) { - pHwData->InitialResource = 4; - init_timer(&pHwData->LEDTimer); - pHwData->LEDTimer.function = hal_led_control; - pHwData->LEDTimer.data = (unsigned long) priv; - pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000); - add_timer(&pHwData->LEDTimer); - - // - // For restrict to vendor's hardware - // - SoftwareSet = hal_software_set( pHwData ); - - #ifdef Vendor2 - // Try to make sure the EEPROM contain - SoftwareSet >>= 8; - if( SoftwareSet != 0x82 ) - return false; - #endif - - Wb35Rx_start(hw); - Wb35Tx_EP2VM_start(priv); - - return true; - } - } - } - - pHwData->SurpriseRemove = 1; - return false; -} - - -void hal_halt(struct hw_data * pHwData, void *ppa_data) -{ - switch( pHwData->InitialResource ) - { - case 4: - case 3: del_timer_sync(&pHwData->LEDTimer); - msleep(100); // Wait for Timer DPC exit 940623.2 - Wb35Rx_destroy( pHwData ); // Release the Rx - case 2: Wb35Tx_destroy( pHwData ); // Release the Tx - case 1: Wb35Reg_destroy( pHwData ); // Release the Wb35 Regisster resources - } -} - -//--------------------------------------------------------------------------------------------------- -void hal_set_beacon_period( struct hw_data * pHwData, u16 beacon_period ) -{ - u32 tmp; - - if( pHwData->SurpriseRemove ) return; - - pHwData->BeaconPeriod = beacon_period; - tmp = pHwData->BeaconPeriod << 16; - tmp |= pHwData->ProbeDelay; - Wb35Reg_Write( pHwData, 0x0848, tmp ); -} - - -static void hal_set_current_channel_ex( struct hw_data * pHwData, ChanInfo channel ) -{ - struct wb35_reg *reg = &pHwData->reg; - - if( pHwData->SurpriseRemove ) - return; - - printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo); - - RFSynthesizer_SwitchingChannel( pHwData, channel );// Switch channel - pHwData->Channel = channel.ChanNo; - pHwData->band = channel.band; - #ifdef _PE_STATE_DUMP_ - printk("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band); - #endif - reg->M28_MacControl &= ~0xff; // Clean channel information field - reg->M28_MacControl |= channel.ChanNo; - Wb35Reg_WriteWithCallbackValue( pHwData, 0x0828, reg->M28_MacControl, - (s8 *)&channel, sizeof(ChanInfo)); -} -//--------------------------------------------------------------------------------------------------- -void hal_set_current_channel( struct hw_data * pHwData, ChanInfo channel ) -{ - hal_set_current_channel_ex( pHwData, channel ); -} -//--------------------------------------------------------------------------------------------------- -void hal_set_accept_broadcast( struct hw_data * pHwData, u8 enable ) -{ - struct wb35_reg *reg = &pHwData->reg; - - if( pHwData->SurpriseRemove ) return; - - reg->M00_MacControl &= ~0x02000000;//The HW value - - if (enable) - reg->M00_MacControl |= 0x02000000;//The HW value - - Wb35Reg_Write( pHwData, 0x0800, reg->M00_MacControl ); -} - -//for wep key error detection, we need to accept broadcast packets to be received temporary. -void hal_set_accept_promiscuous( struct hw_data * pHwData, u8 enable) -{ - struct wb35_reg *reg = &pHwData->reg; - - if (pHwData->SurpriseRemove) return; - if (enable) { - reg->M00_MacControl |= 0x00400000; - Wb35Reg_Write( pHwData, 0x0800, reg->M00_MacControl ); - } else { - reg->M00_MacControl&=~0x00400000; - Wb35Reg_Write( pHwData, 0x0800, reg->M00_MacControl ); - } -} - -void hal_set_accept_multicast( struct hw_data * pHwData, u8 enable ) -{ - struct wb35_reg *reg = &pHwData->reg; - - if( pHwData->SurpriseRemove ) return; - - reg->M00_MacControl &= ~0x01000000;//The HW value - if (enable) reg->M00_MacControl |= 0x01000000;//The HW value - Wb35Reg_Write( pHwData, 0x0800, reg->M00_MacControl ); -} - -void hal_set_accept_beacon( struct hw_data * pHwData, u8 enable ) -{ - struct wb35_reg *reg = &pHwData->reg; - - if( pHwData->SurpriseRemove ) return; - - // 20040108 debug - if( !enable )//Due to SME and MLME are not suitable for 35 - return; - - reg->M00_MacControl &= ~0x04000000;//The HW value - if( enable ) - reg->M00_MacControl |= 0x04000000;//The HW value - - Wb35Reg_Write( pHwData, 0x0800, reg->M00_MacControl ); -} -//--------------------------------------------------------------------------------------------------- - -void hal_stop( struct hw_data * pHwData ) -{ - struct wb35_reg *reg = &pHwData->reg; - - pHwData->Wb35Rx.rx_halt = 1; - Wb35Rx_stop( pHwData ); - - pHwData->Wb35Tx.tx_halt = 1; - Wb35Tx_stop( pHwData ); - - reg->D00_DmaControl &= ~0xc0000000;//Tx Off, Rx Off - Wb35Reg_Write( pHwData, 0x0400, reg->D00_DmaControl ); -} - -unsigned char hal_idle(struct hw_data * pHwData) -{ - struct wb35_reg *reg = &pHwData->reg; - struct wb_usb *pWbUsb = &pHwData->WbUsb; - - if( !pHwData->SurpriseRemove && ( pWbUsb->DetectCount || reg->EP0vm_state!=VM_STOP ) ) - return false; - - return true; -} -//--------------------------------------------------------------------------------------------------- -void hal_set_phy_type( struct hw_data * pHwData, u8 PhyType ) -{ - pHwData->phy_type = PhyType; -} - -void hal_set_radio_mode( struct hw_data * pHwData, unsigned char radio_off) -{ - struct wb35_reg *reg = &pHwData->reg; - - if( pHwData->SurpriseRemove ) return; - - if (radio_off) //disable Baseband receive off - { - pHwData->CurrentRadioSw = 1; // off - reg->M24_MacControl &= 0xffffffbf; - } - else - { - pHwData->CurrentRadioSw = 0; // on - reg->M24_MacControl |= 0x00000040; - } - Wb35Reg_Write( pHwData, 0x0824, reg->M24_MacControl ); -} - -u8 hal_get_antenna_number( struct hw_data * pHwData ) -{ - struct wb35_reg *reg = &pHwData->reg; - - if ((reg->BB2C & BIT(11)) == 0) - return 0; - else - return 1; -} - -//---------------------------------------------------------------------------------------------------- -//0 : radio on; 1: radio off -u8 hal_get_hw_radio_off( struct hw_data * pHwData ) -{ - struct wb35_reg *reg = &pHwData->reg; - - if( pHwData->SurpriseRemove ) return 1; - - //read the bit16 of register U1B0 - Wb35Reg_Read( pHwData, 0x3b0, ®->U1B0 ); - if ((reg->U1B0 & 0x00010000)) { - pHwData->CurrentRadioHw = 1; - return 1; - } else { - pHwData->CurrentRadioHw = 0; - return 0; - } -} - -unsigned char hal_get_dxx_reg( struct hw_data * pHwData, u16 number, u32 * pValue ) -{ - if( number < 0x1000 ) - number += 0x1000; - return Wb35Reg_ReadSync( pHwData, number, pValue ); -} - -unsigned char hal_set_dxx_reg( struct hw_data * pHwData, u16 number, u32 value ) -{ - unsigned char ret; - - if( number < 0x1000 ) - number += 0x1000; - ret = Wb35Reg_WriteSync( pHwData, number, value ); - return ret; -} - -void hal_set_rf_power(struct hw_data * pHwData, u8 PowerIndex) -{ - RFSynthesizer_SetPowerIndex( pHwData, PowerIndex ); -} diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h index efcaefb6aa5..bfdf05d489f 100644 --- a/drivers/staging/winbond/wbhal_f.h +++ b/drivers/staging/winbond/wbhal_f.h @@ -18,10 +18,6 @@ void hal_clear_all_default_key( struct hw_data * pHwData ); void hal_clear_all_group_key( struct hw_data * pHwData ); void hal_clear_all_mapping_key( struct hw_data * pHwData ); void hal_clear_all_key( struct hw_data * pHwData ); -void hal_get_ethernet_address( struct hw_data * pHwData, u8 *current_address ); -void hal_set_ethernet_address( struct hw_data * pHwData, u8 *current_address ); -void hal_get_permanent_address( struct hw_data * pHwData, u8 *pethernet_address ); -u8 hal_init_hardware(struct ieee80211_hw *hw); void hal_set_power_save_mode( struct hw_data * pHwData, unsigned char power_save, unsigned char wakeup, unsigned char dtim ); void hal_get_power_save_mode( struct hw_data * pHwData, u8 *pin_pwr_save ); void hal_set_slot_time( struct hw_data * pHwData, u8 type ); @@ -33,33 +29,21 @@ void hal_resume_sync_bss( struct hw_data * pHwData); void hal_set_aid( struct hw_data * pHwData, u16 aid ); void hal_set_bssid( struct hw_data * pHwData, u8 *pbssid ); void hal_get_bssid( struct hw_data * pHwData, u8 *pbssid ); -void hal_set_beacon_period( struct hw_data * pHwData, u16 beacon_period ); void hal_set_listen_interval( struct hw_data * pHwData, u16 listen_interval ); void hal_set_cap_info( struct hw_data * pHwData, u16 capability_info ); void hal_set_ssid( struct hw_data * pHwData, u8 *pssid, u8 ssid_len ); -void hal_set_current_channel( struct hw_data * pHwData, ChanInfo channel ); -void hal_set_accept_broadcast( struct hw_data * pHwData, u8 enable ); -void hal_set_accept_multicast( struct hw_data * pHwData, u8 enable ); -void hal_set_accept_beacon( struct hw_data * pHwData, u8 enable ); -void hal_stop( struct hw_data * pHwData ); -void hal_halt( struct hw_data * pHwData, void *ppa_data ); void hal_start_tx0( struct hw_data * pHwData ); -void hal_set_phy_type( struct hw_data * pHwData, u8 PhyType ); #define hal_get_cwmin( _A ) ( (_A)->cwmin ) void hal_set_cwmax( struct hw_data * pHwData, u16 cwin_max ); #define hal_get_cwmax( _A ) ( (_A)->cwmax ) void hal_set_rsn_wpa( struct hw_data * pHwData, u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode); void hal_set_connect_info( struct hw_data * pHwData, unsigned char boConnect ); u8 hal_get_est_sq3( struct hw_data * pHwData, u8 Count ); -void hal_set_rf_power( struct hw_data * pHwData, u8 PowerIndex ); // 20060621 Modify -void hal_set_radio_mode( struct hw_data * pHwData, unsigned char boValue); void hal_descriptor_indicate( struct hw_data * pHwData, PDESCRIPTOR pDes ); u8 hal_get_antenna_number( struct hw_data * pHwData ); u32 hal_get_bss_pk_cnt( struct hw_data * pHwData ); #define hal_get_region_from_EEPROM( _A ) ( (_A)->reg.EEPROMRegion ) -void hal_set_accept_promiscuous ( struct hw_data * pHwData, u8 enable); #define hal_get_tx_buffer( _A, _B ) Wb35Tx_get_tx_buffer( _A, _B ) -u8 hal_get_hw_radio_off ( struct hw_data * pHwData ); #define hal_software_set( _A ) (_A->SoftwareSet) #define hal_driver_init_OK( _A ) (_A->IsInitOK) #define hal_rssi_boundary_high( _A ) (_A->RSSI_high) @@ -68,8 +52,6 @@ u8 hal_get_hw_radio_off ( struct hw_data * pHwData ); #define PHY_DEBUG( msg, args... ) -unsigned char hal_get_dxx_reg( struct hw_data * pHwData, u16 number, u32 * pValue ); -unsigned char hal_set_dxx_reg( struct hw_data * pHwData, u16 number, u32 value ); #define hal_get_time_count( _P ) (_P->time_count/10) // return 100ms count #define hal_detect_error( _P ) (_P->WbUsb.DetectCount) @@ -82,10 +64,7 @@ unsigned char hal_set_dxx_reg( struct hw_data * pHwData, u16 number, u32 valu #define hal_get_clear_interrupt(_A) #define hal_ibss_disconnect(_A) hal_stop_sync_bss(_A) #define hal_join_request_stop(_A) -unsigned char hal_idle( struct hw_data * pHwData ); #define hw_get_cxx_reg( _A, _B, _C ) #define hw_set_cxx_reg( _A, _B, _C ) -#define hw_get_dxx_reg( _A, _B, _C ) hal_get_dxx_reg( _A, _B, (u32 *)_C ) -#define hw_set_dxx_reg( _A, _B, _C ) hal_set_dxx_reg( _A, _B, (u32)_C ) diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h index acfebf05d9d..16d0e6f8311 100644 --- a/drivers/staging/winbond/wbhal_s.h +++ b/drivers/staging/winbond/wbhal_s.h @@ -401,7 +401,6 @@ struct hw_data { // For surprise remove u32 SurpriseRemove; // 0: Normal 1: Surprise remove - u8 InitialResource; u8 IsKeyPreSet; u8 CalOneTime; // 20060630.1 diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 3b2d52819b4..745279c528a 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -2,6 +2,12 @@ * Copyright 2008 Pavel Machek <pavel@suse.cz> * * Distribute under GPLv2. + * + * The original driver was written by: + * Jeff Lee <YY_Lee@issc.com.tw> + * + * and was adapted to the 2.6 kernel by: + * Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar> */ #include <net/mac80211.h> #include <linux/usb.h> @@ -13,19 +19,18 @@ #include "wbhal_f.h" #include "wblinux_f.h" -MODULE_AUTHOR("Original by: Jeff Lee<YY_Lee@issc.com.tw> Adapted to 2.6.x by Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>"); MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION("0.1"); static struct usb_device_id wb35_table[] __devinitdata = { - {USB_DEVICE(0x0416, 0x0035)}, - {USB_DEVICE(0x18E8, 0x6201)}, - {USB_DEVICE(0x18E8, 0x6206)}, - {USB_DEVICE(0x18E8, 0x6217)}, - {USB_DEVICE(0x18E8, 0x6230)}, - {USB_DEVICE(0x18E8, 0x6233)}, - {USB_DEVICE(0x1131, 0x2035)}, + { USB_DEVICE(0x0416, 0x0035) }, + { USB_DEVICE(0x18E8, 0x6201) }, + { USB_DEVICE(0x18E8, 0x6206) }, + { USB_DEVICE(0x18E8, 0x6217) }, + { USB_DEVICE(0x18E8, 0x6230) }, + { USB_DEVICE(0x18E8, 0x6233) }, + { USB_DEVICE(0x1131, 0x2035) }, { 0, } }; @@ -36,7 +41,7 @@ static struct ieee80211_rate wbsoft_rates[] = { }; static struct ieee80211_channel wbsoft_channels[] = { - { .center_freq = 2412}, + { .center_freq = 2412 }, }; static struct ieee80211_supported_band wbsoft_band_2GHz = { @@ -47,14 +52,14 @@ static struct ieee80211_supported_band wbsoft_band_2GHz = { }; static int wbsoft_add_interface(struct ieee80211_hw *dev, - struct ieee80211_if_init_conf *conf) + struct ieee80211_if_init_conf *conf) { printk("wbsoft_add interface called\n"); return 0; } static void wbsoft_remove_interface(struct ieee80211_hw *dev, - struct ieee80211_if_init_conf *conf) + struct ieee80211_if_init_conf *conf) { printk("wbsoft_remove interface called\n"); } @@ -79,36 +84,18 @@ static int wbsoft_get_tx_stats(struct ieee80211_hw *hw, } static void wbsoft_configure_filter(struct ieee80211_hw *dev, - unsigned int changed_flags, - unsigned int *total_flags, - int mc_count, struct dev_mc_list *mclist) + unsigned int changed_flags, + unsigned int *total_flags, + int mc_count, struct dev_mc_list *mclist) { - unsigned int bit_nr, new_flags; - u32 mc_filter[2]; - int i; + unsigned int new_flags; new_flags = 0; - if (*total_flags & FIF_PROMISC_IN_BSS) { + if (*total_flags & FIF_PROMISC_IN_BSS) new_flags |= FIF_PROMISC_IN_BSS; - mc_filter[1] = mc_filter[0] = ~0; - } else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32)) { + else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32)) new_flags |= FIF_ALLMULTI; - mc_filter[1] = mc_filter[0] = ~0; - } else { - mc_filter[1] = mc_filter[0] = 0; - for (i = 0; i < mc_count; i++) { - if (!mclist) - break; - printk("Should call ether_crc here\n"); - //bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; - bit_nr = 0; - - bit_nr &= 0x3F; - mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); - mclist = mclist->next; - } - } dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; @@ -124,7 +111,6 @@ static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb) return NETDEV_TX_OK; } - static int wbsoft_start(struct ieee80211_hw *dev) { struct wbsoft_priv *priv = dev->priv; @@ -134,6 +120,127 @@ static int wbsoft_start(struct ieee80211_hw *dev) return 0; } +static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off) +{ + struct wb35_reg *reg = &pHwData->reg; + + if (pHwData->SurpriseRemove) + return; + + if (radio_off) //disable Baseband receive off + { + pHwData->CurrentRadioSw = 1; // off + reg->M24_MacControl &= 0xffffffbf; + } else { + pHwData->CurrentRadioSw = 0; // on + reg->M24_MacControl |= 0x00000040; + } + Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl); +} + +static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period) +{ + u32 tmp; + + if (pHwData->SurpriseRemove) + return; + + pHwData->BeaconPeriod = beacon_period; + tmp = pHwData->BeaconPeriod << 16; + tmp |= pHwData->ProbeDelay; + Wb35Reg_Write(pHwData, 0x0848, tmp); +} + +static void +hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel) +{ + struct wb35_reg *reg = &pHwData->reg; + + if (pHwData->SurpriseRemove) + return; + + printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo); + + RFSynthesizer_SwitchingChannel(pHwData, channel); // Switch channel + pHwData->Channel = channel.ChanNo; + pHwData->band = channel.band; +#ifdef _PE_STATE_DUMP_ + printk("Set channel is %d, band =%d\n", pHwData->Channel, + pHwData->band); +#endif + reg->M28_MacControl &= ~0xff; // Clean channel information field + reg->M28_MacControl |= channel.ChanNo; + Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl, + (s8 *) & channel, sizeof(ChanInfo)); +} + +static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel) +{ + hal_set_current_channel_ex(pHwData, channel); +} + +static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable) +{ + struct wb35_reg *reg = &pHwData->reg; + + if (pHwData->SurpriseRemove) + return; + + reg->M00_MacControl &= ~0x02000000; //The HW value + + if (enable) + reg->M00_MacControl |= 0x02000000; //The HW value + + Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); +} + +//for wep key error detection, we need to accept broadcast packets to be received temporary. +static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable) +{ + struct wb35_reg *reg = &pHwData->reg; + + if (pHwData->SurpriseRemove) + return; + if (enable) { + reg->M00_MacControl |= 0x00400000; + Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); + } else { + reg->M00_MacControl &= ~0x00400000; + Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); + } +} + +static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable) +{ + struct wb35_reg *reg = &pHwData->reg; + + if (pHwData->SurpriseRemove) + return; + + reg->M00_MacControl &= ~0x01000000; //The HW value + if (enable) + reg->M00_MacControl |= 0x01000000; //The HW value + Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); +} + +static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable) +{ + struct wb35_reg *reg = &pHwData->reg; + + if (pHwData->SurpriseRemove) + return; + + // 20040108 debug + if (!enable) //Due to SME and MLME are not suitable for 35 + return; + + reg->M00_MacControl &= ~0x04000000; //The HW value + if (enable) + reg->M00_MacControl |= 0x04000000; //The HW value + + Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); +} + static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) { struct wbsoft_priv *priv = dev->priv; @@ -142,36 +249,18 @@ static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) printk("wbsoft_config called\n"); + /* Should use channel_num, or something, as that is already pre-translated */ ch.band = 1; - ch.ChanNo = 1; /* Should use channel_num, or something, as that is already pre-translated */ - + ch.ChanNo = 1; hal_set_current_channel(&priv->sHwData, ch); hal_set_beacon_period(&priv->sHwData, conf->beacon_int); -// hal_set_cap_info(&priv->sHwData, ?? ); -// hal_set_ssid(struct hw_data * pHwData, u8 * pssid, u8 ssid_len); ?? hal_set_accept_broadcast(&priv->sHwData, 1); - hal_set_accept_promiscuous(&priv->sHwData, 1); - hal_set_accept_multicast(&priv->sHwData, 1); - hal_set_accept_beacon(&priv->sHwData, 1); - hal_set_radio_mode(&priv->sHwData, 0); - //hal_set_antenna_number( struct hw_data * pHwData, u8 number ) - //hal_set_rf_power(struct hw_data * pHwData, u8 PowerIndex) - - -// hal_start_bss(&priv->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE); ?? + hal_set_accept_promiscuous(&priv->sHwData, 1); + hal_set_accept_multicast(&priv->sHwData, 1); + hal_set_accept_beacon(&priv->sHwData, 1); + hal_set_radio_mode(&priv->sHwData, 0); -//void hal_set_rates(struct hw_data * pHwData, u8 * pbss_rates, -// u8 length, unsigned char basic_rate_set) - - return 0; -} - -static int wbsoft_config_interface(struct ieee80211_hw *dev, - struct ieee80211_vif *vif, - struct ieee80211_if_conf *conf) -{ - printk("wbsoft_config_interface called\n"); return 0; } @@ -183,63 +272,448 @@ static u64 wbsoft_get_tsf(struct ieee80211_hw *dev) static const struct ieee80211_ops wbsoft_ops = { .tx = wbsoft_tx, - .start = wbsoft_start, /* Start can be pretty much empty as we do wb35_hw_init() during probe? */ + .start = wbsoft_start, .stop = wbsoft_stop, .add_interface = wbsoft_add_interface, .remove_interface = wbsoft_remove_interface, .config = wbsoft_config, - .config_interface = wbsoft_config_interface, .configure_filter = wbsoft_configure_filter, .get_stats = wbsoft_get_stats, .get_tx_stats = wbsoft_get_tx_stats, .get_tsf = wbsoft_get_tsf, -// conf_tx: hal_set_cwmin()/hal_set_cwmax; }; -static unsigned char wb35_hw_init(struct ieee80211_hw *hw) +static void +hal_set_ethernet_address(struct hw_data *pHwData, u8 * current_address) +{ + u32 ltmp[2]; + + if (pHwData->SurpriseRemove) + return; + + memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN); + + ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress); + ltmp[1] = + cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff; + + Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT); +} + +static void +hal_get_permanent_address(struct hw_data *pHwData, u8 * pethernet_address) +{ + if (pHwData->SurpriseRemove) + return; + + memcpy(pethernet_address, pHwData->PermanentMacAddress, 6); +} + +static void hal_stop(struct hw_data *pHwData) +{ + struct wb35_reg *reg = &pHwData->reg; + + pHwData->Wb35Rx.rx_halt = 1; + Wb35Rx_stop(pHwData); + + pHwData->Wb35Tx.tx_halt = 1; + Wb35Tx_stop(pHwData); + + reg->D00_DmaControl &= ~0xc0000000; //Tx Off, Rx Off + Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl); +} + +static unsigned char hal_idle(struct hw_data *pHwData) +{ + struct wb35_reg *reg = &pHwData->reg; + struct wb_usb *pWbUsb = &pHwData->WbUsb; + + if (!pHwData->SurpriseRemove + && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP)) + return false; + + return true; +} + +u8 hal_get_antenna_number(struct hw_data *pHwData) +{ + struct wb35_reg *reg = &pHwData->reg; + + if ((reg->BB2C & BIT(11)) == 0) + return 0; + else + return 1; +} + +/* 0 : radio on; 1: radio off */ +static u8 hal_get_hw_radio_off(struct hw_data * pHwData) +{ + struct wb35_reg *reg = &pHwData->reg; + + if (pHwData->SurpriseRemove) + return 1; + + //read the bit16 of register U1B0 + Wb35Reg_Read(pHwData, 0x3b0, ®->U1B0); + if ((reg->U1B0 & 0x00010000)) { + pHwData->CurrentRadioHw = 1; + return 1; + } else { + pHwData->CurrentRadioHw = 0; + return 0; + } +} + +static u8 LED_GRAY[20] = { + 0, 3, 4, 6, 8, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 8, 6, 4, 2 +}; + +static u8 LED_GRAY2[30] = { + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 15, 14, 13, 12, 11, 10, 9, 8 +}; + +static void hal_led_control(unsigned long data) +{ + struct wbsoft_priv *adapter = (struct wbsoft_priv *)data; + struct hw_data *pHwData = &adapter->sHwData; + struct wb35_reg *reg = &pHwData->reg; + u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT; + u32 TimeInterval = 500, ltmp, ltmp2; + ltmp = 0; + + if (pHwData->SurpriseRemove) + return; + + if (pHwData->LED_control) { + ltmp2 = pHwData->LED_control & 0xff; + if (ltmp2 == 5) // 5 is WPS mode + { + TimeInterval = 100; + ltmp2 = (pHwData->LED_control >> 8) & 0xff; + switch (ltmp2) { + case 1: // [0.2 On][0.1 Off]... + pHwData->LED_Blinking %= 3; + ltmp = 0x1010; // Led 1 & 0 Green and Red + if (pHwData->LED_Blinking == 2) // Turn off + ltmp = 0; + break; + case 2: // [0.1 On][0.1 Off]... + pHwData->LED_Blinking %= 2; + ltmp = 0x0010; // Led 0 red color + if (pHwData->LED_Blinking) // Turn off + ltmp = 0; + break; + 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]... + pHwData->LED_Blinking %= 15; + ltmp = 0x0010; // Led 0 red color + if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2)) // Turn off 0.6 sec + ltmp = 0; + break; + case 4: // [300 On][ off ] + ltmp = 0x1000; // Led 1 Green color + if (pHwData->LED_Blinking >= 3000) + ltmp = 0; // led maybe on after 300sec * 32bit counter overlap. + break; + } + pHwData->LED_Blinking++; + + reg->U1BC_LEDConfigure = ltmp; + if (LEDSet != 7) // Only 111 mode has 2 LEDs on PCB. + { + reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; // Copy LED result to each LED control register + reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8; + } + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); + } + } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) // If radio off + { + if (reg->U1BC_LEDConfigure & 0x1010) { + reg->U1BC_LEDConfigure &= ~0x1010; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); + } + } else { + switch (LEDSet) { + case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing + if (!pHwData->LED_LinkOn) // Blink only if not Link On + { + // Blinking if scanning is on progress + if (pHwData->LED_Scanning) { + if (pHwData->LED_Blinking == 0) { + reg->U1BC_LEDConfigure |= 0x10; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On + pHwData->LED_Blinking = 1; + TimeInterval = 300; + } else { + reg->U1BC_LEDConfigure &= ~0x10; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + pHwData->LED_Blinking = 0; + TimeInterval = 300; + } + } else { + //Turn Off LED_0 + if (reg->U1BC_LEDConfigure & 0x10) { + reg->U1BC_LEDConfigure &= ~0x10; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + } + } + } else { + // Turn On LED_0 + if ((reg->U1BC_LEDConfigure & 0x10) == 0) { + reg->U1BC_LEDConfigure |= 0x10; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + } + } + break; + + case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing + if (!pHwData->LED_LinkOn) // Blink only if not Link On + { + // Blinking if scanning is on progress + if (pHwData->LED_Scanning) { + if (pHwData->LED_Blinking == 0) { + reg->U1BC_LEDConfigure &= ~0xf; + reg->U1BC_LEDConfigure |= 0x10; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On + pHwData->LED_Blinking = 1; + TimeInterval = 300; + } else { + reg->U1BC_LEDConfigure &= ~0x1f; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + pHwData->LED_Blinking = 0; + TimeInterval = 300; + } + } else { + // 20060901 Gray blinking if in disconnect state and not scanning + ltmp = reg->U1BC_LEDConfigure; + reg->U1BC_LEDConfigure &= ~0x1f; + if (LED_GRAY2[(pHwData->LED_Blinking % 30)]) { + reg->U1BC_LEDConfigure |= 0x10; + reg->U1BC_LEDConfigure |= + LED_GRAY2[(pHwData->LED_Blinking % 30)]; + } + pHwData->LED_Blinking++; + if (reg->U1BC_LEDConfigure != ltmp) + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + TimeInterval = 100; + } + } else { + // Turn On LED_0 + if ((reg->U1BC_LEDConfigure & 0x10) == 0) { + reg->U1BC_LEDConfigure |= 0x10; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + } + } + break; + + case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing + if (!pHwData->LED_LinkOn) // Blink only if not Link On + { + // Blinking if scanning is on progress + if (pHwData->LED_Scanning) { + if (pHwData->LED_Blinking == 0) { + reg->U1BC_LEDConfigure |= + 0x1000; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On + pHwData->LED_Blinking = 1; + TimeInterval = 300; + } else { + reg->U1BC_LEDConfigure &= + ~0x1000; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off + pHwData->LED_Blinking = 0; + TimeInterval = 300; + } + } else { + //Turn Off LED_1 + if (reg->U1BC_LEDConfigure & 0x1000) { + reg->U1BC_LEDConfigure &= + ~0x1000; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off + } + } + } else { + // Is transmitting/receiving ?? + if ((adapter->RxByteCount != + pHwData->RxByteCountLast) + || (adapter->TxByteCount != + pHwData->TxByteCountLast)) { + if ((reg->U1BC_LEDConfigure & 0x3000) != + 0x3000) { + reg->U1BC_LEDConfigure |= + 0x3000; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On + } + // Update variable + pHwData->RxByteCountLast = + adapter->RxByteCount; + pHwData->TxByteCountLast = + adapter->TxByteCount; + TimeInterval = 200; + } else { + // Turn On LED_1 and blinking if transmitting/receiving + if ((reg->U1BC_LEDConfigure & 0x3000) != + 0x1000) { + reg->U1BC_LEDConfigure &= + ~0x3000; + reg->U1BC_LEDConfigure |= + 0x1000; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On + } + } + } + break; + + default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active + if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) { + reg->U1BC_LEDConfigure |= 0x3000; // LED_1 is always on and event enable + Wb35Reg_Write(pHwData, 0x03bc, + reg->U1BC_LEDConfigure); + } + + if (pHwData->LED_Blinking) { + // Gray blinking + reg->U1BC_LEDConfigure &= ~0x0f; + reg->U1BC_LEDConfigure |= 0x10; + reg->U1BC_LEDConfigure |= + LED_GRAY[(pHwData->LED_Blinking - 1) % 20]; + Wb35Reg_Write(pHwData, 0x03bc, + reg->U1BC_LEDConfigure); + + pHwData->LED_Blinking += 2; + if (pHwData->LED_Blinking < 40) + TimeInterval = 100; + else { + pHwData->LED_Blinking = 0; // Stop blinking + reg->U1BC_LEDConfigure &= ~0x0f; + Wb35Reg_Write(pHwData, 0x03bc, + reg->U1BC_LEDConfigure); + } + break; + } + + if (pHwData->LED_LinkOn) { + if (!(reg->U1BC_LEDConfigure & 0x10)) // Check the LED_0 + { + //Try to turn ON LED_0 after gray blinking + reg->U1BC_LEDConfigure |= 0x10; + pHwData->LED_Blinking = 1; //Start blinking + TimeInterval = 50; + } + } else { + if (reg->U1BC_LEDConfigure & 0x10) // Check the LED_0 + { + reg->U1BC_LEDConfigure &= ~0x10; + Wb35Reg_Write(pHwData, 0x03bc, + reg->U1BC_LEDConfigure); + } + } + break; + } + + //20060828.1 Active send null packet to avoid AP disconnect + if (pHwData->LED_LinkOn) { + pHwData->NullPacketCount += TimeInterval; + if (pHwData->NullPacketCount >= + DEFAULT_NULL_PACKET_COUNT) { + pHwData->NullPacketCount = 0; + } + } + } + + pHwData->time_count += TimeInterval; + Wb35Tx_CurrentTime(adapter, pHwData->time_count); // 20060928 add + pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval); + add_timer(&pHwData->LEDTimer); +} + +static int hal_init_hardware(struct ieee80211_hw *hw) { struct wbsoft_priv *priv = hw->priv; - struct hw_data * pHwData; - u8 *pMacAddr; - u8 *pMacAddr2; - u32 InitStep = 0; - u8 EEPROM_region; - u8 HwRadioOff; - - // - // Setting default value for Linux - // - priv->sLocalPara.region_INF = REGION_AUTO; - priv->sLocalPara.TxRateMode = RATE_AUTO; - priv->sLocalPara.bMacOperationMode = MODE_802_11_BG; // B/G mode - priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold; - priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; - hal_set_phy_type( &priv->sHwData, RF_WB_242_1 ); - priv->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE; - priv->sLocalPara.bPreambleMode = AUTO_MODE; + struct hw_data *pHwData = &priv->sHwData; + u16 SoftwareSet; + + pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME; + pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; + + if (!Wb35Reg_initial(pHwData)) + goto error_reg_destroy; + + if (!Wb35Tx_initial(pHwData)) + goto error_tx_destroy; + + if (!Wb35Rx_initial(pHwData)) + goto error_rx_destroy; + + init_timer(&pHwData->LEDTimer); + pHwData->LEDTimer.function = hal_led_control; + pHwData->LEDTimer.data = (unsigned long)priv; + pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(1000); + add_timer(&pHwData->LEDTimer); + + SoftwareSet = hal_software_set(pHwData); + +#ifdef Vendor2 + // Try to make sure the EEPROM contain + SoftwareSet >>= 8; + if (SoftwareSet != 0x82) + return false; +#endif + + Wb35Rx_start(hw); + Wb35Tx_EP2VM_start(priv); + + return 0; + +error_rx_destroy: + Wb35Rx_destroy(pHwData); +error_tx_destroy: + Wb35Tx_destroy(pHwData); +error_reg_destroy: + Wb35Reg_destroy(pHwData); + + pHwData->SurpriseRemove = 1; + return -EINVAL; +} + +static int wb35_hw_init(struct ieee80211_hw *hw) +{ + struct wbsoft_priv *priv = hw->priv; + struct hw_data *pHwData = &priv->sHwData; + u8 EEPROM_region; + u8 HwRadioOff; + u8 *pMacAddr2; + u8 *pMacAddr; + int err; + + pHwData->phy_type = RF_DECIDE_BY_INF; + + priv->Mds.TxRTSThreshold = DEFAULT_RTSThreshold; + priv->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; + + priv->sLocalPara.region_INF = REGION_AUTO; + priv->sLocalPara.TxRateMode = RATE_AUTO; + priv->sLocalPara.bMacOperationMode = MODE_802_11_BG; + priv->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE; + priv->sLocalPara.bPreambleMode = AUTO_MODE; + priv->sLocalPara.bWepKeyError = false; + priv->sLocalPara.bToSelfPacketReceived = false; + priv->sLocalPara.WepKeyDetectTimerCount = 2 * 100; /* 2 seconds */ + priv->sLocalPara.RadioOffStatus.boSwRadioOff = false; - pHwData = &priv->sHwData; - hal_set_phy_type( pHwData, RF_DECIDE_BY_INF ); - - //added by ws for wep key error detection - priv->sLocalPara.bWepKeyError= false; - priv->sLocalPara.bToSelfPacketReceived = false; - priv->sLocalPara.WepKeyDetectTimerCount= 2 * 100; /// 2 seconds - - // Initial USB hal - InitStep = 1; - pHwData = &priv->sHwData; - if (!hal_init_hardware(hw)) + + err = hal_init_hardware(hw); + if (err) goto error; - EEPROM_region = hal_get_region_from_EEPROM( pHwData ); + EEPROM_region = hal_get_region_from_EEPROM(pHwData); if (EEPROM_region != REGION_AUTO) priv->sLocalPara.region = EEPROM_region; else { if (priv->sLocalPara.region_INF != REGION_AUTO) priv->sLocalPara.region = priv->sLocalPara.region_INF; else - priv->sLocalPara.region = REGION_USA; //default setting + priv->sLocalPara.region = REGION_USA; /* default setting */ } // Get Software setting flag from hal @@ -247,93 +721,80 @@ static unsigned char wb35_hw_init(struct ieee80211_hw *hw) if (hal_software_set(pHwData) & 0x00000001) priv->sLocalPara.boAntennaDiversity = true; - // - // For TS module - // - InitStep = 2; - - // For MDS module - InitStep = 3; Mds_initial(priv); - //======================================= - // Initialize the SME, SCAN, MLME, ROAM - //======================================= - InitStep = 4; - InitStep = 5; - InitStep = 6; - - // If no user-defined address in the registry, use the addresss "burned" on the NIC instead. + /* + * If no user-defined address in the registry, use the addresss + * "burned" on the NIC instead. + */ pMacAddr = priv->sLocalPara.ThisMacAddress; pMacAddr2 = priv->sLocalPara.PermanentAddress; - hal_get_permanent_address( pHwData, priv->sLocalPara.PermanentAddress );// Reading ethernet address from EEPROM + + /* Reading ethernet address from EEPROM */ + hal_get_permanent_address(pHwData, priv->sLocalPara.PermanentAddress); if (memcmp(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH) == 0) memcpy(pMacAddr, pMacAddr2, MAC_ADDR_LENGTH); else { - // Set the user define MAC address - hal_set_ethernet_address(pHwData, priv->sLocalPara.ThisMacAddress); + /* Set the user define MAC address */ + hal_set_ethernet_address(pHwData, + priv->sLocalPara.ThisMacAddress); } - //get current antenna priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData); #ifdef _PE_STATE_DUMP_ printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo); #endif - hal_get_hw_radio_off( pHwData ); + hal_get_hw_radio_off(pHwData); - // Waiting for HAL setting OK + /* Waiting for HAL setting OK */ while (!hal_idle(pHwData)) msleep(10); MTO_Init(priv); - HwRadioOff = hal_get_hw_radio_off( pHwData ); + HwRadioOff = hal_get_hw_radio_off(pHwData); priv->sLocalPara.RadioOffStatus.boHwRadioOff = !!HwRadioOff; - hal_set_radio_mode( pHwData, (unsigned char)(priv->sLocalPara.RadioOffStatus.boSwRadioOff || priv->sLocalPara.RadioOffStatus.boHwRadioOff) ); + hal_set_radio_mode(pHwData, + (unsigned char)(priv->sLocalPara.RadioOffStatus. + boSwRadioOff + || priv->sLocalPara.RadioOffStatus. + boHwRadioOff)); - hal_driver_init_OK(pHwData) = 1; // Notify hal that the driver is ready now. - //set a tx power for reference..... -// sme_set_tx_power_level(priv, 12); FIXME? - return true; + /* Notify hal that the driver is ready now. */ + hal_driver_init_OK(pHwData) = 1; error: - switch (InitStep) { - case 5: - case 4: - case 3: Mds_Destroy( priv ); - case 2: - case 1: hal_halt( pHwData, NULL ); - case 0: break; - } - - return false; + return err; } -static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table) +static int wb35_probe(struct usb_interface *intf, + const struct usb_device_id *id_table) { - struct wb_usb *pWbUsb; - struct usb_host_interface *interface; - struct usb_endpoint_descriptor *endpoint; - u32 ltmp; struct usb_device *udev = interface_to_usbdev(intf); - struct wbsoft_priv *priv; + struct usb_endpoint_descriptor *endpoint; + struct usb_host_interface *interface; struct ieee80211_hw *dev; + struct wbsoft_priv *priv; + struct wb_usb *pWbUsb; int nr, err; + u32 ltmp; usb_get_dev(udev); - // 20060630.2 Check the device if it already be opened - nr = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ), - 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, - 0x0, 0x400, <mp, 4, HZ*100 ); + /* Check the device if it already be opened */ + nr = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + 0x01, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x0, 0x400, <mp, 4, HZ * 100); if (nr < 0) { err = nr; goto error; } + /* Is already initialized? */ ltmp = cpu_to_le32(ltmp); - if (ltmp) { // Is already initialized? + if (ltmp) { err = -EBUSY; goto error; } @@ -351,23 +812,22 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id pWbUsb = &priv->sHwData.WbUsb; pWbUsb->udev = udev; - interface = intf->cur_altsetting; - endpoint = &interface->endpoint[0].desc; + interface = intf->cur_altsetting; + endpoint = &interface->endpoint[0].desc; if (endpoint[2].wMaxPacketSize == 512) { printk("[w35und] Working on USB 2.0\n"); pWbUsb->IsUsb20 = 1; } - if (!wb35_hw_init(dev)) { - err = -EINVAL; + err = wb35_hw_init(dev); + if (err) goto error_free_hw; - } SET_IEEE80211_DEV(dev, &udev->dev); { - struct hw_data * pHwData = &priv->sHwData; - unsigned char dev_addr[MAX_ADDR_LEN]; + struct hw_data *pHwData = &priv->sHwData; + unsigned char dev_addr[MAX_ADDR_LEN]; hal_get_permanent_address(pHwData, dev_addr); SET_IEEE80211_PERM_ADDR(dev, dev_addr); } @@ -397,22 +857,31 @@ error: return err; } +static void hal_halt(struct hw_data *pHwData) +{ + del_timer_sync(&pHwData->LEDTimer); + /* XXX: Wait for Timer DPC exit. */ + msleep(100); + Wb35Rx_destroy(pHwData); + Wb35Tx_destroy(pHwData); + Wb35Reg_destroy(pHwData); +} + static void wb35_hw_halt(struct wbsoft_priv *adapter) { - Mds_Destroy( adapter ); + Mds_Destroy(adapter); - // Turn off Rx and Tx hardware ability - hal_stop( &adapter->sHwData ); + /* Turn off Rx and Tx hardware ability */ + hal_stop(&adapter->sHwData); #ifdef _PE_USB_INI_DUMP_ printk("[w35und] Hal_stop O.K.\n"); #endif - msleep(100);// Waiting Irp completed + /* Waiting Irp completed */ + msleep(100); - // Halt the HAL - hal_halt(&adapter->sHwData, NULL); + hal_halt(&adapter->sHwData); } - static void wb35_disconnect(struct usb_interface *intf) { struct ieee80211_hw *hw = usb_get_intfdata(intf); |