static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct vnt_private *priv = hw->priv; priv->vif = vif; switch (vif->type) { case NL80211_IFTYPE_STATION: break; case NL80211_IFTYPE_ADHOC: vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST); vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC); break; case NL80211_IFTYPE_AP: vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST); vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_AP); break; default: return -EOPNOTSUPP; } priv->op_mode = vif->type; vnt_set_bss_mode(priv); /* LED blink on TX */ vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_INTER); return 0; }
void vnt_disable_power_saving(struct vnt_private *priv) { /* disable power saving hw function */ vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0, 0, 0, NULL); /* clear AutoSleep */ vnt_mac_reg_bits_off(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); /* set always listen beacon */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN); }
static void vnt_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct vnt_private *priv = hw->priv; switch (vif->type) { case NL80211_IFTYPE_STATION: break; case NL80211_IFTYPE_ADHOC: vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC); break; case NL80211_IFTYPE_AP: vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_AP); break; default: break; } vnt_radio_power_off(priv); priv->op_mode = NL80211_IFTYPE_UNSPECIFIED; /* LED slow blink */ vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW); }
/* * Description: Turn off Radio power * * Parameters: * In: * priv - The adapter to be turned off * Out: * none * * Return Value: true if success; otherwise false * */ int vnt_radio_power_off(struct vnt_private *priv) { int ret = true; switch (priv->rf_type) { case RF_AL2230: case RF_AL2230S: case RF_AIROHA7230: case RF_VT3226: case RF_VT3226D0: case RF_VT3342A0: vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); break; } vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_RXON); vnt_set_deep_sleep(priv); vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD); return ret; }
/* * Description: Set NIC media channel * * Parameters: * In: * pDevice - The adapter to be set * connection_channel - Channel to be set * Out: * none */ void vnt_set_channel(struct vnt_private *priv, u32 connection_channel) { if (connection_channel > CB_MAX_CHANNEL || !connection_channel) return; /* clear NAV */ vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV); /* Set Channel[7] = 0 to tell H/W channel is changing now. */ vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0); vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL, connection_channel, 0, 0, NULL); vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL, (u8)(connection_channel | 0x80)); }
void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval) { u16 aid = priv->current_aid | BIT(14) | BIT(15); /* set period of power up before TBTT */ vnt_mac_write_word(priv, MAC_REG_PWBT, C_PWBT); if (priv->op_mode != NL80211_IFTYPE_ADHOC) /* set AID */ vnt_mac_write_word(priv, MAC_REG_AIDATIM, aid); /* Warren:06-18-2004,the sequence must follow * PSEN->AUTOSLEEP->GO2DOZE */ /* enable power saving hw function */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_PSEN); /* Set AutoSleep */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); /* Warren:MUST turn on this once before turn on AUTOSLEEP ,or the * AUTOSLEEP doesn't work */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_GO2DOZE); if (listen_interval >= 2) { /* clear always listen beacon */ vnt_mac_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_ALBCN); /* first time set listen next beacon */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN); } else { /* always listen beacon */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN); } dev_dbg(&priv->usb->dev, "PS:Power Saving Mode Enable...\n"); }
static void vnt_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf, u32 changed) { struct vnt_private *priv = hw->priv; priv->current_aid = conf->aid; if (changed & BSS_CHANGED_BSSID && conf->bssid) vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid); if (changed & BSS_CHANGED_BASIC_RATES) { priv->basic_rates = conf->basic_rates; vnt_update_top_rates(priv); dev_dbg(&priv->usb->dev, "basic rates %x\n", conf->basic_rates); } if (changed & BSS_CHANGED_ERP_PREAMBLE) { if (conf->use_short_preamble) { vnt_mac_enable_barker_preamble_mode(priv); priv->preamble_type = true; } else { vnt_mac_disable_barker_preamble_mode(priv); priv->preamble_type = false; } } if (changed & BSS_CHANGED_ERP_CTS_PROT) { if (conf->use_cts_prot) vnt_mac_enable_protect_mode(priv); else vnt_mac_disable_protect_mode(priv); } if (changed & BSS_CHANGED_ERP_SLOT) { if (conf->use_short_slot) priv->short_slot_time = true; else priv->short_slot_time = false; vnt_set_short_slot_time(priv); vnt_set_vga_gain_offset(priv, priv->bb_vga[0]); vnt_update_pre_ed_threshold(priv, false); } if (changed & BSS_CHANGED_TXPOWER) vnt_rf_setpower(priv, priv->current_rate, conf->chandef.chan->hw_value); if (changed & BSS_CHANGED_BEACON_ENABLED) { dev_dbg(&priv->usb->dev, "Beacon enable %d\n", conf->enable_beacon); if (conf->enable_beacon) { vnt_beacon_enable(priv, vif, conf); vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX); } else { vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); } } if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INFO) && priv->op_mode != NL80211_IFTYPE_AP) { if (conf->assoc && conf->beacon_rate) { vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); vnt_adjust_tsf(priv, conf->beacon_rate->hw_value, conf->sync_tsf, priv->current_tsf); vnt_mac_set_beacon_interval(priv, conf->beacon_int); vnt_reset_next_tbtt(priv, conf->beacon_int); } else { vnt_clear_current_tsf(priv); vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); } } }
/* * initialization of MAC & BBP registers */ static int vnt_init_registers(struct vnt_private *priv) { struct vnt_cmd_card_init *init_cmd = &priv->init_command; struct vnt_rsp_card_init *init_rsp = &priv->init_response; u8 antenna; int ii; int status = STATUS_SUCCESS; u8 tmp; u8 calib_tx_iq = 0, calib_tx_dc = 0, calib_rx_iq = 0; dev_dbg(&priv->usb->dev, "---->INIbInitAdapter. [%d][%d]\n", DEVICE_INIT_COLD, priv->packet_type); if (!vnt_check_firmware_version(priv)) { if (vnt_download_firmware(priv) == true) { if (vnt_firmware_branch_to_sram(priv) == false) { dev_dbg(&priv->usb->dev, " vnt_firmware_branch_to_sram fail\n"); return false; } } else { dev_dbg(&priv->usb->dev, "FIRMWAREbDownload fail\n"); return false; } } if (!vnt_vt3184_init(priv)) { dev_dbg(&priv->usb->dev, "vnt_vt3184_init fail\n"); return false; } init_cmd->init_class = DEVICE_INIT_COLD; init_cmd->exist_sw_net_addr = priv->exist_sw_net_addr; for (ii = 0; ii < 6; ii++) init_cmd->sw_net_addr[ii] = priv->current_net_addr[ii]; init_cmd->short_retry_limit = priv->short_retry_limit; init_cmd->long_retry_limit = priv->long_retry_limit; /* issue card_init command to device */ status = vnt_control_out(priv, MESSAGE_TYPE_CARDINIT, 0, 0, sizeof(struct vnt_cmd_card_init), (u8 *)init_cmd); if (status != STATUS_SUCCESS) { dev_dbg(&priv->usb->dev, "Issue Card init fail\n"); return false; } status = vnt_control_in(priv, MESSAGE_TYPE_INIT_RSP, 0, 0, sizeof(struct vnt_rsp_card_init), (u8 *)init_rsp); if (status != STATUS_SUCCESS) { dev_dbg(&priv->usb->dev, "Cardinit request in status fail!\n"); return false; } /* local ID for AES functions */ status = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_LOCALID, MESSAGE_REQUEST_MACREG, 1, &priv->local_id); if (status != STATUS_SUCCESS) return false; /* do MACbSoftwareReset in MACvInitialize */ priv->top_ofdm_basic_rate = RATE_24M; priv->top_cck_basic_rate = RATE_1M; /* target to IF pin while programming to RF chip */ priv->power = 0xFF; priv->cck_pwr = priv->eeprom[EEP_OFS_PWR_CCK]; priv->ofdm_pwr_g = priv->eeprom[EEP_OFS_PWR_OFDMG]; /* load power table */ for (ii = 0; ii < 14; ii++) { priv->cck_pwr_tbl[ii] = priv->eeprom[ii + EEP_OFS_CCK_PWR_TBL]; if (priv->cck_pwr_tbl[ii] == 0) priv->cck_pwr_tbl[ii] = priv->cck_pwr; priv->ofdm_pwr_tbl[ii] = priv->eeprom[ii + EEP_OFS_OFDM_PWR_TBL]; if (priv->ofdm_pwr_tbl[ii] == 0) priv->ofdm_pwr_tbl[ii] = priv->ofdm_pwr_g; } /* * original zonetype is USA, but custom zonetype is Europe, * then need to recover 12, 13, 14 channels with 11 channel */ for (ii = 11; ii < 14; ii++) { priv->cck_pwr_tbl[ii] = priv->cck_pwr_tbl[10]; priv->ofdm_pwr_tbl[ii] = priv->ofdm_pwr_tbl[10]; } priv->ofdm_pwr_a = 0x34; /* same as RFbMA2829SelectChannel */ /* load OFDM A power table */ for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { priv->ofdm_a_pwr_tbl[ii] = priv->eeprom[ii + EEP_OFS_OFDMA_PWR_TBL]; if (priv->ofdm_a_pwr_tbl[ii] == 0) priv->ofdm_a_pwr_tbl[ii] = priv->ofdm_pwr_a; } antenna = priv->eeprom[EEP_OFS_ANTENNA]; if (antenna & EEP_ANTINV) priv->tx_rx_ant_inv = true; else priv->tx_rx_ant_inv = false; antenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); if (antenna == 0) /* if not set default is both */ antenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); if (antenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) { priv->tx_antenna_mode = ANT_B; priv->rx_antenna_sel = 1; if (priv->tx_rx_ant_inv) priv->rx_antenna_mode = ANT_A; else priv->rx_antenna_mode = ANT_B; } else { priv->rx_antenna_sel = 0; if (antenna & EEP_ANTENNA_AUX) { priv->tx_antenna_mode = ANT_A; if (priv->tx_rx_ant_inv) priv->rx_antenna_mode = ANT_B; else priv->rx_antenna_mode = ANT_A; } else { priv->tx_antenna_mode = ANT_B; if (priv->tx_rx_ant_inv) priv->rx_antenna_mode = ANT_A; else priv->rx_antenna_mode = ANT_B; } } /* Set initial antenna mode */ vnt_set_antenna_mode(priv, priv->rx_antenna_mode); /* get Auto Fall Back type */ priv->auto_fb_ctrl = AUTO_FB_0; /* default Auto Mode */ priv->bb_type = BB_TYPE_11G; /* get RFType */ priv->rf_type = init_rsp->rf_type; /* load vt3266 calibration parameters in EEPROM */ if (priv->rf_type == RF_VT3226D0) { if ((priv->eeprom[EEP_OFS_MAJOR_VER] == 0x1) && (priv->eeprom[EEP_OFS_MINOR_VER] >= 0x4)) { calib_tx_iq = priv->eeprom[EEP_OFS_CALIB_TX_IQ]; calib_tx_dc = priv->eeprom[EEP_OFS_CALIB_TX_DC]; calib_rx_iq = priv->eeprom[EEP_OFS_CALIB_RX_IQ]; if (calib_tx_iq || calib_tx_dc || calib_rx_iq) { /* CR255, enable TX/RX IQ and * DC compensation mode */ vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xff, 0x03); /* CR251, TX I/Q Imbalance Calibration */ vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xfb, calib_tx_iq); /* CR252, TX DC-Offset Calibration */ vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xfC, calib_tx_dc); /* CR253, RX I/Q Imbalance Calibration */ vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xfd, calib_rx_iq); } else { /* CR255, turn off * BB Calibration compensation */ vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xff, 0x0); } } } /* get permanent network address */ memcpy(priv->permanent_net_addr, init_rsp->net_addr, 6); ether_addr_copy(priv->current_net_addr, priv->permanent_net_addr); /* if exist SW network address, use it */ dev_dbg(&priv->usb->dev, "Network address = %pM\n", priv->current_net_addr); /* * set BB and packet type at the same time * set Short Slot Time, xIFS, and RSPINF */ if (priv->bb_type == BB_TYPE_11A) priv->short_slot_time = true; else priv->short_slot_time = false; vnt_set_short_slot_time(priv); priv->radio_ctl = priv->eeprom[EEP_OFS_RADIOCTL]; if ((priv->radio_ctl & EEP_RADIOCTL_ENABLE) != 0) { status = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_GPIOCTL1, MESSAGE_REQUEST_MACREG, 1, &tmp); if (status != STATUS_SUCCESS) return false; if ((tmp & GPIO3_DATA) == 0) vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD); else vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD); } vnt_mac_set_led(priv, LEDSTS_TMLEN, 0x38); vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW); vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL0, 0x01); vnt_radio_power_on(priv); dev_dbg(&priv->usb->dev, "<----INIbInitAdapter Exit\n"); return true; }