From c4b8dddef54f0db049944f95f32b1b28cc84346f Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Thu, 10 Feb 2011 20:59:42 +0300 Subject: [PATCH] --- yaml --- r: 237384 b: refs/heads/master c: e3fb592b15602196d38b225dc78aab8d631a5f89 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/net/wireless/ath/ath9k/ath9k.h | 2 - trunk/drivers/net/wireless/ath/ath9k/beacon.c | 37 +- trunk/drivers/net/wireless/ath/ath9k/main.c | 35 +- trunk/drivers/net/wireless/iwlwifi/iwl-2000.c | 3 +- .../net/wireless/iwlwifi/iwl-agn-lib.c | 12 +- trunk/drivers/net/wireless/p54/eeprom.c | 208 +-- trunk/drivers/net/wireless/p54/eeprom.h | 7 - trunk/drivers/net/wireless/p54/fwio.c | 12 +- trunk/drivers/net/wireless/p54/lmac.h | 1 - trunk/drivers/net/wireless/p54/main.c | 2 - trunk/drivers/net/wireless/p54/p54.h | 6 +- .../drivers/net/wireless/p54/p54spi_eeprom.h | 9 +- trunk/drivers/net/wireless/p54/txrx.c | 6 +- trunk/drivers/net/wireless/rt2x00/rt2800lib.c | 12 +- trunk/drivers/net/wireless/rt2x00/rt61pci.c | 12 +- trunk/drivers/net/wireless/rt2x00/rt73usb.c | 12 +- trunk/drivers/net/wireless/rtlwifi/Makefile | 3 +- trunk/drivers/net/wireless/rtlwifi/base.h | 1 - trunk/drivers/net/wireless/rtlwifi/debug.h | 1 - trunk/drivers/net/wireless/rtlwifi/pci.c | 85 +- trunk/drivers/net/wireless/rtlwifi/pci.h | 12 +- .../net/wireless/rtlwifi/rtl8192c/dm_common.c | 1388 ----------------- .../net/wireless/rtlwifi/rtl8192ce/dm.c | 1359 +++++++++++++++- .../net/wireless/rtlwifi/rtl8192ce/dm.h | 1 - .../net/wireless/rtlwifi/rtl8192ce/fw.c | 49 +- .../net/wireless/rtlwifi/rtl8192ce/phy.c | 99 +- .../net/wireless/rtlwifi/rtl8192ce/sw.c | 1 - .../net/wireless/rtlwifi/rtl8192ce/sw.h | 2 - .../net/wireless/rtlwifi/rtl8192ce/trx.c | 33 - .../net/wireless/rtlwifi/rtl8192ce/trx.h | 2 - trunk/drivers/net/wireless/rtlwifi/usb.c | 1035 ------------ trunk/drivers/net/wireless/rtlwifi/usb.h | 164 -- trunk/drivers/net/wireless/rtlwifi/wifi.h | 47 +- trunk/drivers/net/wireless/zd1211rw/zd_chip.c | 35 +- trunk/drivers/net/wireless/zd1211rw/zd_def.h | 2 +- trunk/drivers/net/wireless/zd1211rw/zd_usb.c | 177 +-- trunk/drivers/net/wireless/zd1211rw/zd_usb.h | 9 +- trunk/net/bluetooth/l2cap_sock.c | 1 + trunk/net/mac80211/ibss.c | 11 +- trunk/net/mac80211/rx.c | 12 +- 41 files changed, 1699 insertions(+), 3208 deletions(-) delete mode 100644 trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c delete mode 100644 trunk/drivers/net/wireless/rtlwifi/usb.c delete mode 100644 trunk/drivers/net/wireless/rtlwifi/usb.h diff --git a/[refs] b/[refs] index b3659ccb12bf..20731a17d530 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c269a20393500e84e8cbae23ca6d65e1107433c4 +refs/heads/master: e3fb592b15602196d38b225dc78aab8d631a5f89 diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 4d60583b0f69..56dee3719f95 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -348,7 +348,6 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid struct ath_vif { int av_bslot; - bool is_bslot_active; __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ enum nl80211_iftype av_opmode; struct ath_buf *av_bcbuf; @@ -403,7 +402,6 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); int ath_beaconq_config(struct ath_softc *sc); -void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); /*******/ /* ANI */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/beacon.c b/trunk/drivers/net/wireless/ath/ath9k/beacon.c index a4bdfdb043ef..ed6e7d66fc38 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/beacon.c +++ b/trunk/drivers/net/wireless/ath/ath9k/beacon.c @@ -143,7 +143,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, avp = (void *)vif->drv_priv; cabq = sc->beacon.cabq; - if ((avp->av_bcbuf == NULL) || !avp->is_bslot_active) + if (avp->av_bcbuf == NULL) return NULL; /* Release the old beacon first */ @@ -249,7 +249,6 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) for (slot = 0; slot < ATH_BCBUF; slot++) if (sc->beacon.bslot[slot] == NULL) { avp->av_bslot = slot; - avp->is_bslot_active = false; /* NB: keep looking for a double slot */ if (slot == 0 || !sc->beacon.bslot[slot-1]) @@ -316,7 +315,6 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) ath_err(common, "dma_mapping_error on beacon alloc\n"); return -ENOMEM; } - avp->is_bslot_active = true; return 0; } @@ -751,36 +749,3 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) sc->sc_flags |= SC_OP_BEACONS; } - -void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath_vif *avp; - int slot; - bool found = false; - - ath9k_ps_wakeup(sc); - if (status) { - for (slot = 0; slot < ATH_BCBUF; slot++) { - if (sc->beacon.bslot[slot]) { - avp = (void *)sc->beacon.bslot[slot]->drv_priv; - if (avp->is_bslot_active) { - found = true; - break; - } - } - } - if (found) { - /* Re-enable beaconing */ - ah->imask |= ATH9K_INT_SWBA; - ath9k_hw_set_interrupts(ah, ah->imask); - } - } else { - /* Disable SWBA interrupt */ - ah->imask &= ~ATH9K_INT_SWBA; - ath9k_hw_set_interrupts(ah, ah->imask); - tasklet_kill(&sc->bcon_tasklet); - ath9k_hw_stoptxdma(ah, sc->beacon.beaconq); - } - ath9k_ps_restore(sc); -} diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 31f0fad72391..8469d7c8744a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -1293,10 +1293,24 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc, { struct ath_vif *avp = (void *)vif->drv_priv; - ath9k_set_beaconing_status(sc, false); + /* Disable SWBA interrupt */ + sc->sc_ah->imask &= ~ATH9K_INT_SWBA; + ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); + tasklet_kill(&sc->bcon_tasklet); + ath9k_ps_restore(sc); + ath_beacon_return(sc, avp); - ath9k_set_beaconing_status(sc, true); sc->sc_flags &= ~SC_OP_BEACONS; + + if (sc->nbcnvifs > 0) { + /* Re-enable beaconing */ + sc->sc_ah->imask |= ATH9K_INT_SWBA; + ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); + ath9k_ps_restore(sc); + } } static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) @@ -1424,17 +1438,16 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, if (ath9k_uses_beacons(vif->type)) { int error; + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); /* This may fail because upper levels do not have beacons * properly configured yet. That's OK, we assume it * will be properly configured and then we will be notified * in the info_changed method and set up beacons properly * there. */ - ath9k_set_beaconing_status(sc, false); error = ath_beacon_alloc(sc, vif); if (!error) ath_beacon_config(sc, vif); - ath9k_set_beaconing_status(sc, true); } } @@ -1907,11 +1920,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, /* Enable transmission of beacons (AP, IBSS, MESH) */ if ((changed & BSS_CHANGED_BEACON) || ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { - ath9k_set_beaconing_status(sc, false); + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); error = ath_beacon_alloc(sc, vif); if (!error) ath_beacon_config(sc, vif); - ath9k_set_beaconing_status(sc, true); } if (changed & BSS_CHANGED_ERP_SLOT) { @@ -1934,12 +1946,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, } /* Disable transmission of beacons */ - if ((changed & BSS_CHANGED_BEACON_ENABLED) && - !bss_conf->enable_beacon) { - ath9k_set_beaconing_status(sc, false); - avp->is_bslot_active = false; - ath9k_set_beaconing_status(sc, true); - } + if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); if (changed & BSS_CHANGED_BEACON_INT) { cur_conf->beacon_interval = bss_conf->beacon_int; @@ -1949,11 +1957,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, */ if (vif->type == NL80211_IFTYPE_AP) { sc->sc_flags |= SC_OP_TSF_RESET; - ath9k_set_beaconing_status(sc, false); + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); error = ath_beacon_alloc(sc, vif); if (!error) ath_beacon_config(sc, vif); - ath9k_set_beaconing_status(sc, true); } else { ath_beacon_config(sc, vif); } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c index 30483e27ce5c..3c5dd36ff417 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -265,8 +265,7 @@ static struct iwl_lib_ops iwl2000_lib = { .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, .rx_handler_setup = iwlagn_rx_handler_setup, - .setup_deferred_work = iwlagn_bt_setup_deferred_work, - .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, + .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, .load_ucode = iwlagn_load_ucode, .dump_nic_event_log = iwl_dump_nic_event_log, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 325ff5c89ee8..3aa486437509 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1832,7 +1832,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) * IBSS mode (no proper uCode support for coex then). */ if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { - bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; + bt_cmd.flags = 0; } else { bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << IWLAGN_BT_FLAG_COEX_MODE_SHIFT; @@ -1869,11 +1869,6 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) struct iwl_rxon_context *ctx; int smps_request = -1; - if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { - /* bt coex disabled */ - return; - } - /* * Note: bt_traffic_load can be overridden by scan complete and * coex profile notifications. Ignore that since only bad consequence @@ -2027,11 +2022,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; - if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { - /* bt coex disabled */ - return; - } - IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); diff --git a/trunk/drivers/net/wireless/p54/eeprom.c b/trunk/drivers/net/wireless/p54/eeprom.c index f54e15fcd623..35b09aa0529b 100644 --- a/trunk/drivers/net/wireless/p54/eeprom.c +++ b/trunk/drivers/net/wireless/p54/eeprom.c @@ -55,17 +55,6 @@ static struct ieee80211_rate p54_arates[] = { { .bitrate = 540, .hw_value = 11, }, }; -static struct p54_rssi_db_entry p54_rssi_default = { - /* - * The defaults are taken from usb-logs of the - * vendor driver. So, they should be safe to - * use in case we can't get a match from the - * rssi <-> dBm conversion database. - */ - .mul = 130, - .add = -398, -}; - #define CHAN_HAS_CAL BIT(0) #define CHAN_HAS_LIMIT BIT(1) #define CHAN_HAS_CURVE BIT(2) @@ -98,27 +87,13 @@ static int p54_get_band_from_freq(u16 freq) return -1; } -static int same_band(u16 freq, u16 freq2) -{ - return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2); -} - static int p54_compare_channels(const void *_a, const void *_b) { const struct p54_channel_entry *a = _a; const struct p54_channel_entry *b = _b; - return a->freq - b->freq; -} - -static int p54_compare_rssichan(const void *_a, - const void *_b) -{ - const struct p54_rssi_db_entry *a = _a; - const struct p54_rssi_db_entry *b = _b; - - return a->freq - b->freq; + return a->index - b->index; } static int p54_fill_band_bitrates(struct ieee80211_hw *dev, @@ -170,26 +145,25 @@ static int p54_generate_band(struct ieee80211_hw *dev, for (i = 0, j = 0; (j < list->band_channel_num[band]) && (i < list->entries); i++) { - struct p54_channel_entry *chan = &list->channels[i]; - if (chan->band != band) + if (list->channels[i].band != band) continue; - if (chan->data != CHAN_HAS_ALL) { - wiphy_err(dev->wiphy, "%s%s%s is/are missing for " - "channel:%d [%d MHz].\n", - (chan->data & CHAN_HAS_CAL ? "" : + if (list->channels[i].data != CHAN_HAS_ALL) { + wiphy_err(dev->wiphy, + "%s%s%s is/are missing for channel:%d [%d MHz].\n", + (list->channels[i].data & CHAN_HAS_CAL ? "" : " [iqauto calibration data]"), - (chan->data & CHAN_HAS_LIMIT ? "" : + (list->channels[i].data & CHAN_HAS_LIMIT ? "" : " [output power limits]"), - (chan->data & CHAN_HAS_CURVE ? "" : + (list->channels[i].data & CHAN_HAS_CURVE ? "" : " [curve data]"), - chan->index, chan->freq); + list->channels[i].index, list->channels[i].freq); continue; } - tmp->channels[j].band = chan->band; - tmp->channels[j].center_freq = chan->freq; + tmp->channels[j].band = list->channels[i].band; + tmp->channels[j].center_freq = list->channels[i].freq; j++; } @@ -317,7 +291,7 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) } } - /* sort the channel list by frequency */ + /* sort the list by the channel index */ sort(list->channels, list->entries, sizeof(struct p54_channel_entry), p54_compare_channels, NULL); @@ -436,118 +410,33 @@ static int p54_convert_rev1(struct ieee80211_hw *dev, static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2", "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" }; -static int p54_parse_rssical(struct ieee80211_hw *dev, - u8 *data, int len, u16 type) +static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len, + u16 type) { struct p54_common *priv = dev->priv; - struct p54_rssi_db_entry *entry; - size_t db_len, entries; - int offset = 0, i; - - if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) { - entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2; - if (len != sizeof(struct pda_rssi_cal_entry) * entries) { - wiphy_err(dev->wiphy, "rssical size mismatch.\n"); - goto err_data; - } - } else { - /* - * Some devices (Dell 1450 USB, Xbow 5GHz card, etc...) - * have an empty two byte header. - */ - if (*((__le16 *)&data[offset]) == cpu_to_le16(0)) - offset += 2; - - entries = (len - offset) / - sizeof(struct pda_rssi_cal_ext_entry); + int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0; + int entry_size = sizeof(struct pda_rssi_cal_entry) + offset; + int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2; + int i; - if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) || - entries <= 0) { - wiphy_err(dev->wiphy, "invalid rssi database.\n"); - goto err_data; - } - } - - db_len = sizeof(*entry) * entries; - priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL); - if (!priv->rssi_db) - return -ENOMEM; - - priv->rssi_db->offset = 0; - priv->rssi_db->entries = entries; - priv->rssi_db->entry_size = sizeof(*entry); - priv->rssi_db->len = db_len; - - entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset); - if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) { - struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset]; + if (len != (entry_size * num_entries)) { + wiphy_err(dev->wiphy, + "unknown rssi calibration data packing type:(%x) len:%d.\n", + type, len); - for (i = 0; i < entries; i++) { - entry[i].freq = le16_to_cpu(cal[i].freq); - entry[i].mul = (s16) le16_to_cpu(cal[i].mul); - entry[i].add = (s16) le16_to_cpu(cal[i].add); - } - } else { - struct pda_rssi_cal_entry *cal = (void *) &data[offset]; - - for (i = 0; i < entries; i++) { - u16 freq; - switch (i) { - case IEEE80211_BAND_2GHZ: - freq = 2437; - break; - case IEEE80211_BAND_5GHZ: - freq = 5240; - break; - } + print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, + data, len); - entry[i].freq = freq; - entry[i].mul = (s16) le16_to_cpu(cal[i].mul); - entry[i].add = (s16) le16_to_cpu(cal[i].add); - } + wiphy_err(dev->wiphy, "please report this issue.\n"); + return; } - /* sort the list by channel frequency */ - sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL); - return 0; - -err_data: - wiphy_err(dev->wiphy, - "rssi calibration data packing type:(%x) len:%d.\n", - type, len); - - print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len); - - wiphy_err(dev->wiphy, "please report this issue.\n"); - return -EINVAL; -} - -struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq) -{ - struct p54_rssi_db_entry *entry = (void *)(priv->rssi_db->data + - priv->rssi_db->offset); - int i, found = -1; - - for (i = 0; i < priv->rssi_db->entries; i++) { - if (!same_band(freq, entry[i].freq)) - continue; - - if (found == -1) { - found = i; - continue; - } - - /* nearest match */ - if (abs(freq - entry[i].freq) < - abs(freq - entry[found].freq)) { - found = i; - continue; - } else { - break; - } + for (i = 0; i < num_entries; i++) { + struct pda_rssi_cal_entry *cal = data + + (offset + i * entry_size); + priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul); + priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add); } - - return found < 0 ? &p54_rssi_default : &entry[found]; } static void p54_parse_default_country(struct ieee80211_hw *dev, @@ -738,30 +627,21 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) case PDR_RSSI_LINEAR_APPROXIMATION: case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND: case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED: - err = p54_parse_rssical(dev, entry->data, data_len, - le16_to_cpu(entry->code)); - if (err) - goto err; + p54_parse_rssical(dev, entry->data, data_len, + le16_to_cpu(entry->code)); break; - case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: { - struct pda_custom_wrapper *pda = (void *) entry->data; - __le16 *src; - u16 *dst; + case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: { + __le16 *src = (void *) entry->data; + s16 *dst = (void *) &priv->rssical_db; int i; - if (priv->rssi_db || data_len < sizeof(*pda)) - break; - - priv->rssi_db = p54_convert_db(pda, data_len); - if (!priv->rssi_db) - break; - - src = (void *) priv->rssi_db->data; - dst = (void *) priv->rssi_db->data; - - for (i = 0; i < priv->rssi_db->entries; i++) + if (data_len != sizeof(priv->rssical_db)) { + err = -EINVAL; + goto err; + } + for (i = 0; i < sizeof(priv->rssical_db) / + sizeof(*src); i++) *(dst++) = (s16) le16_to_cpu(*(src++)); - } break; case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: { @@ -837,8 +717,6 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) SET_IEEE80211_PERM_ADDR(dev, perm_addr); } - priv->cur_rssi = &p54_rssi_default; - wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", dev->wiphy->perm_addr, priv->version, p54_rf_chips[priv->rxhw]); @@ -849,11 +727,9 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) kfree(priv->iq_autocal); kfree(priv->output_limit); kfree(priv->curve_data); - kfree(priv->rssi_db); priv->iq_autocal = NULL; priv->output_limit = NULL; priv->curve_data = NULL; - priv->rssi_db = NULL; wiphy_err(dev->wiphy, "eeprom parse failed!\n"); return err; diff --git a/trunk/drivers/net/wireless/p54/eeprom.h b/trunk/drivers/net/wireless/p54/eeprom.h index afde72b84606..9051aef11249 100644 --- a/trunk/drivers/net/wireless/p54/eeprom.h +++ b/trunk/drivers/net/wireless/p54/eeprom.h @@ -81,12 +81,6 @@ struct pda_pa_curve_data { u8 data[0]; } __packed; -struct pda_rssi_cal_ext_entry { - __le16 freq; - __le16 mul; - __le16 add; -} __packed; - struct pda_rssi_cal_entry { __le16 mul; __le16 add; @@ -185,7 +179,6 @@ struct pda_custom_wrapper { /* used by our modificated eeprom image */ #define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD -#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 0xCAFF #define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF #define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D diff --git a/trunk/drivers/net/wireless/p54/fwio.c b/trunk/drivers/net/wireless/p54/fwio.c index 0d3d108f6fe2..92b9b1f05fd5 100644 --- a/trunk/drivers/net/wireless/p54/fwio.c +++ b/trunk/drivers/net/wireless/p54/fwio.c @@ -397,9 +397,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) union p54_scan_body_union *body; struct p54_scan_tail_rate *rate; struct pda_rssi_cal_entry *rssi; - struct p54_rssi_db_entry *rssi_data; unsigned int i; void *entry; + int band = priv->hw->conf.channel->band; __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq); skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + @@ -503,14 +503,13 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) } rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi)); - rssi_data = p54_rssi_find(priv, le16_to_cpu(freq)); - rssi->mul = cpu_to_le16(rssi_data->mul); - rssi->add = cpu_to_le16(rssi_data->add); + rssi->mul = cpu_to_le16(priv->rssical_db[band].mul); + rssi->add = cpu_to_le16(priv->rssical_db[band].add); if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { /* Longbow frontend needs ever more */ rssi = (void *) skb_put(skb, sizeof(*rssi)); - rssi->mul = cpu_to_le16(rssi_data->longbow_unkn); - rssi->add = cpu_to_le16(rssi_data->longbow_unk2); + rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn); + rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2); } if (priv->fw_var >= 0x509) { @@ -524,7 +523,6 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) hdr->len = cpu_to_le16(skb->len - sizeof(*hdr)); p54_tx(priv, skb); - priv->cur_rssi = rssi_data; return 0; err: diff --git a/trunk/drivers/net/wireless/p54/lmac.h b/trunk/drivers/net/wireless/p54/lmac.h index 5ca117e6f95b..04b63ec80fa4 100644 --- a/trunk/drivers/net/wireless/p54/lmac.h +++ b/trunk/drivers/net/wireless/p54/lmac.h @@ -551,7 +551,6 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, /* eeprom */ int p54_download_eeprom(struct p54_common *priv, void *buf, u16 offset, u16 len); -struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *p, const u16 freq); /* utility */ u8 *p54_find_ie(struct sk_buff *skb, u8 ie); diff --git a/trunk/drivers/net/wireless/p54/main.c b/trunk/drivers/net/wireless/p54/main.c index 0a78e666e2d1..622d27b6d8f2 100644 --- a/trunk/drivers/net/wireless/p54/main.c +++ b/trunk/drivers/net/wireless/p54/main.c @@ -642,12 +642,10 @@ void p54_free_common(struct ieee80211_hw *dev) kfree(priv->iq_autocal); kfree(priv->output_limit); kfree(priv->curve_data); - kfree(priv->rssi_db); kfree(priv->used_rxkeys); priv->iq_autocal = NULL; priv->output_limit = NULL; priv->curve_data = NULL; - priv->rssi_db = NULL; priv->used_rxkeys = NULL; ieee80211_free_hw(dev); } diff --git a/trunk/drivers/net/wireless/p54/p54.h b/trunk/drivers/net/wireless/p54/p54.h index f951c8f31863..43a3b2ead81a 100644 --- a/trunk/drivers/net/wireless/p54/p54.h +++ b/trunk/drivers/net/wireless/p54/p54.h @@ -116,8 +116,7 @@ struct p54_edcf_queue_param { __le16 txop; } __packed; -struct p54_rssi_db_entry { - u16 freq; +struct p54_rssi_linear_approximation { s16 mul; s16 add; s16 longbow_unkn; @@ -198,14 +197,13 @@ struct p54_common { u8 rx_diversity_mask; u8 tx_diversity_mask; unsigned int output_power; - struct p54_rssi_db_entry *cur_rssi; int noise; /* calibration, output power limit and rssi<->dBm conversation data */ struct pda_iq_autocal_entry *iq_autocal; unsigned int iq_autocal_len; struct p54_cal_database *curve_data; struct p54_cal_database *output_limit; - struct p54_cal_database *rssi_db; + struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS]; struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS]; /* BBP/MAC state */ diff --git a/trunk/drivers/net/wireless/p54/p54spi_eeprom.h b/trunk/drivers/net/wireless/p54/p54spi_eeprom.h index 0b7bfb0adcf2..d592cbd34d78 100644 --- a/trunk/drivers/net/wireless/p54/p54spi_eeprom.h +++ b/trunk/drivers/net/wireless/p54/p54spi_eeprom.h @@ -65,10 +65,9 @@ static unsigned char p54spi_eeprom[] = { 0x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */ 0x08, 0x08, 0x08, 0x08, -0x0a, 0x00, 0xff, 0xca, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 */ - 0x01, 0x00, 0x0a, 0x00, - 0x00, 0x00, 0x0a, 0x00, - 0x85, 0x09, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, +0x09, 0x00, 0xad, 0xde, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */ + 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* struct pda_custom_wrapper */ 0x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */ @@ -672,7 +671,7 @@ static unsigned char p54spi_eeprom[] = { 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, /* PDR_END */ - 0xb6, 0x04, + 0x67, 0x99, }; #endif /* P54SPI_EEPROM_H */ diff --git a/trunk/drivers/net/wireless/p54/txrx.c b/trunk/drivers/net/wireless/p54/txrx.c index 917d5d948e3c..f618b9623e5a 100644 --- a/trunk/drivers/net/wireless/p54/txrx.c +++ b/trunk/drivers/net/wireless/p54/txrx.c @@ -273,9 +273,11 @@ void p54_tx(struct p54_common *priv, struct sk_buff *skb) static int p54_rssi_to_dbm(struct p54_common *priv, int rssi) { + int band = priv->hw->conf.channel->band; + if (priv->rxhw != 5) { - return ((rssi * priv->cur_rssi->mul) / 64 + - priv->cur_rssi->add) / 4; + return ((rssi * priv->rssical_db[band].mul) / 64 + + priv->rssical_db[band].add) / 4; } else { /* * TODO: find the correct formula diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index 7a68a67c506a..c9bf074342ba 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -773,14 +773,13 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); unsigned int beacon_base; unsigned int padding_len; - u32 orig_reg, reg; + u32 reg; /* * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); - orig_reg = reg; rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); @@ -811,14 +810,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) * Write entire beacon with TXWI and padding to register. */ padding_len = roundup(entry->skb->len, 4) - entry->skb->len; - if (padding_len && skb_pad(entry->skb, padding_len)) { - ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); - /* skb freed by skb_pad() on failure */ - entry->skb = NULL; - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg); - return; - } - + skb_pad(entry->skb, padding_len); beacon_base = HW_BEACON_OFFSET(entry->entry_idx); rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, entry->skb->len + padding_len); diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.c b/trunk/drivers/net/wireless/rt2x00/rt61pci.c index 927a4a3e0eeb..dd2164d4d57b 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt61pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.c @@ -1978,14 +1978,13 @@ static void rt61pci_write_beacon(struct queue_entry *entry, struct queue_entry_priv_pci *entry_priv = entry->priv_data; unsigned int beacon_base; unsigned int padding_len; - u32 orig_reg, reg; + u32 reg; /* * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); - orig_reg = reg; rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); @@ -2003,14 +2002,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry, * Write entire beacon with descriptor and padding to register. */ padding_len = roundup(entry->skb->len, 4) - entry->skb->len; - if (padding_len && skb_pad(entry->skb, padding_len)) { - ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); - /* skb freed by skb_pad() on failure */ - entry->skb = NULL; - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, orig_reg); - return; - } - + skb_pad(entry->skb, padding_len); beacon_base = HW_BEACON_OFFSET(entry->entry_idx); rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, entry_priv->desc, TXINFO_SIZE); diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index 6e9981a1dd7f..5ff72deea8d4 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -1533,14 +1533,13 @@ static void rt73usb_write_beacon(struct queue_entry *entry, struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; unsigned int beacon_base; unsigned int padding_len; - u32 orig_reg, reg; + u32 reg; /* * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); - orig_reg = reg; rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); @@ -1564,14 +1563,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry, * Write entire beacon with descriptor and padding to register. */ padding_len = roundup(entry->skb->len, 4) - entry->skb->len; - if (padding_len && skb_pad(entry->skb, padding_len)) { - ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); - /* skb freed by skb_pad() on failure */ - entry->skb = NULL; - rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg); - return; - } - + skb_pad(entry->skb, padding_len); beacon_base = HW_BEACON_OFFSET(entry->entry_idx); rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, entry->skb->len + padding_len); diff --git a/trunk/drivers/net/wireless/rtlwifi/Makefile b/trunk/drivers/net/wireless/rtlwifi/Makefile index efbff2f478bf..2a7a4384f8ee 100644 --- a/trunk/drivers/net/wireless/rtlwifi/Makefile +++ b/trunk/drivers/net/wireless/rtlwifi/Makefile @@ -8,7 +8,6 @@ rtlwifi-objs := \ pci.o \ ps.o \ rc.o \ - regd.o \ - usb.o + regd.o obj-$(CONFIG_RTL8192CE) += rtl8192ce/ diff --git a/trunk/drivers/net/wireless/rtlwifi/base.h b/trunk/drivers/net/wireless/rtlwifi/base.h index c95982b030da..3de5a14745f1 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.h +++ b/trunk/drivers/net/wireless/rtlwifi/base.h @@ -30,7 +30,6 @@ #define __RTL_BASE_H__ #define RTL_DUMMY_OFFSET 0 -#define RTL_RX_DESC_SIZE 24 #define RTL_DUMMY_UNIT 8 #define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) #define RTL_TX_DESC_SIZE 32 diff --git a/trunk/drivers/net/wireless/rtlwifi/debug.h b/trunk/drivers/net/wireless/rtlwifi/debug.h index e4aa8687408c..08bdec2ceda4 100644 --- a/trunk/drivers/net/wireless/rtlwifi/debug.h +++ b/trunk/drivers/net/wireless/rtlwifi/debug.h @@ -105,7 +105,6 @@ #define COMP_MAC80211 BIT(26) #define COMP_REGD BIT(27) #define COMP_CHAN BIT(28) -#define COMP_USB BIT(29) /*-------------------------------------------------------------- Define the rt_print components diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index a508ea51a1f8..1758d4463247 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -690,6 +690,75 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) } +void _rtl_pci_tx_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + int prio; + + for (prio = 0; prio < RTL_PCI_MAX_TX_QUEUE_COUNT; prio++) { + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct rtl_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + u8 own; + + /* + *beacon packet will only use the first + *descriptor defautly, and the own may not + *be cleared by the hardware, and + *beacon will free in prepare beacon + */ + if (prio == BEACON_QUEUE || prio == TXCMD_QUEUE || + prio == HCCA_QUEUE) + break; + + own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)entry, + true, + HW_DESC_OWN); + + if (own) + break; + + skb = __skb_dequeue(&ring->queue); + pci_unmap_single(rtlpci->pdev, + le32_to_cpu(rtlpriv->cfg->ops-> + get_desc((u8 *) entry, + true, + HW_DESC_TXBUFF_ADDR)), + skb->len, PCI_DMA_TODEVICE); + + ring->idx = (ring->idx + 1) % ring->entries; + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + info->flags |= IEEE80211_TX_STAT_ACK; + /*info->status.rates[0].count = 1; */ + + ieee80211_tx_status_irqsafe(hw, skb); + + if ((ring->entries - skb_queue_len(&ring->queue)) + == 2 && prio != BEACON_QUEUE) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("more desc left, wake " + "skb_queue@%d,ring->idx = %d," + "skb_queue_len = 0x%d\n", + prio, ring->idx, + skb_queue_len(&ring->queue))); + + ieee80211_wake_queue(hw, + skb_get_queue_mapping + (skb)); + } + + skb = NULL; + } + } +} + static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) { struct ieee80211_hw *hw = dev_id; @@ -1204,7 +1273,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) return 0; } -static unsigned int _rtl_mac_to_hwqueue(u16 fc, +unsigned int _rtl_mac_to_hwqueue(u16 fc, unsigned int mac80211_queue_index) { unsigned int hw_queue_index; @@ -1243,7 +1312,7 @@ static unsigned int _rtl_mac_to_hwqueue(u16 fc, return hw_queue_index; } -static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -1360,7 +1429,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return 0; } -static void rtl_pci_deinit(struct ieee80211_hw *hw) +void rtl_pci_deinit(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -1375,7 +1444,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw) } -static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) +int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) { struct rtl_priv *rtlpriv = rtl_priv(hw); int err; @@ -1392,7 +1461,7 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) return 1; } -static int rtl_pci_start(struct ieee80211_hw *hw) +int rtl_pci_start(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -1427,7 +1496,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw) return 0; } -static void rtl_pci_stop(struct ieee80211_hw *hw) +void rtl_pci_stop(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -1769,7 +1838,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, ieee80211_free_hw(hw); if (rtlpriv->io.pci_mem_start != 0) - pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); + pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start); fail2: pci_release_regions(pdev); @@ -1819,7 +1888,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev) } if (rtlpriv->io.pci_mem_start != 0) { - pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); + pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start); pci_release_regions(pdev); } diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.h b/trunk/drivers/net/wireless/rtlwifi/pci.h index 0caa81429726..d36a66939958 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.h +++ b/trunk/drivers/net/wireless/rtlwifi/pci.h @@ -244,34 +244,34 @@ int rtl_pci_resume(struct pci_dev *pdev); static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) { - return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr); } static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr) { - return readw((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + return readw((u8 *) rtlpriv->io.pci_mem_start + addr); } static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr) { - return readl((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + return readl((u8 *) rtlpriv->io.pci_mem_start + addr); } static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) { - writeb(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr); } static inline void pci_write16_async(struct rtl_priv *rtlpriv, u32 addr, u16 val) { - writew(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr); } static inline void pci_write32_async(struct rtl_priv *rtlpriv, u32 addr, u32 val) { - writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); + writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr); } static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val) diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c deleted file mode 100644 index b08b7802f04f..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ /dev/null @@ -1,1388 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -struct dig_t dm_digtable; -static struct ps_t dm_pstable; - -static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { - 0x7f8001fe, - 0x788001e2, - 0x71c001c7, - 0x6b8001ae, - 0x65400195, - 0x5fc0017f, - 0x5a400169, - 0x55400155, - 0x50800142, - 0x4c000130, - 0x47c0011f, - 0x43c0010f, - 0x40000100, - 0x3c8000f2, - 0x390000e4, - 0x35c000d7, - 0x32c000cb, - 0x300000c0, - 0x2d4000b5, - 0x2ac000ab, - 0x288000a2, - 0x26000098, - 0x24000090, - 0x22000088, - 0x20000080, - 0x1e400079, - 0x1c800072, - 0x1b00006c, - 0x19800066, - 0x18000060, - 0x16c0005b, - 0x15800056, - 0x14400051, - 0x1300004c, - 0x12000048, - 0x11000044, - 0x10000040, -}; - -static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, - {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, - {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, - {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, - {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, - {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, - {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, - {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, - {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, - {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, - {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, - {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, - {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, - {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, - {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, - {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, - {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, - {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, - {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, - {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, - {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, - {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, - {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, - {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} -}; - -static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, - {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, - {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, - {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, - {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, - {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, - {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, - {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, - {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, - {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, - {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, - {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} -}; - -static void rtl92c_dm_diginit(struct ieee80211_hw *hw) -{ - dm_digtable.dig_enable_flag = true; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable.cur_igvalue = 0x20; - dm_digtable.pre_igvalue = 0x0; - dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; - dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; - dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; - dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; - dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; - dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; - dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; - dm_digtable.rx_gain_range_max = DM_DIG_MAX; - dm_digtable.rx_gain_range_min = DM_DIG_MIN; - dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; - dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; - dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX; - dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; -} - -static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - long rssi_val_min = 0; - - if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) && - (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) { - if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) - rssi_val_min = - (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > - rtlpriv->dm.undecorated_smoothed_pwdb) ? - rtlpriv->dm.undecorated_smoothed_pwdb : - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - else - rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; - } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT || - dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) { - rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; - } else if (dm_digtable.curmultista_connectstate == - DIG_MULTISTA_CONNECT) { - rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - } - - return (u8) rssi_val_min; -} - -static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) -{ - u32 ret_value; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); - falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); - falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); - falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); - falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); - falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; - - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); - falsealm_cnt->cnt_cck_fail = ret_value; - - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); - falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; - falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + - falsealm_cnt->cnt_mcs_fail + - falsealm_cnt->cnt_cck_fail); - - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " - "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", - falsealm_cnt->cnt_parity_fail, - falsealm_cnt->cnt_rate_illegal, - falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", - falsealm_cnt->cnt_ofdm_fail, - falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); -} - -static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value_igi = dm_digtable.cur_igvalue; - - if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) - value_igi--; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) - value_igi += 0; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) - value_igi++; - else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) - value_igi += 2; - if (value_igi > DM_DIG_FA_UPPER) - value_igi = DM_DIG_FA_UPPER; - else if (value_igi < DM_DIG_FA_LOWER) - value_igi = DM_DIG_FA_LOWER; - if (rtlpriv->falsealm_cnt.cnt_all > 10000) - value_igi = 0x32; - - dm_digtable.cur_igvalue = value_igi; - rtl92c_dm_write_dig(hw); -} - -static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) { - if ((dm_digtable.backoff_val - 2) < - dm_digtable.backoff_val_range_min) - dm_digtable.backoff_val = - dm_digtable.backoff_val_range_min; - else - dm_digtable.backoff_val -= 2; - } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) { - if ((dm_digtable.backoff_val + 2) > - dm_digtable.backoff_val_range_max) - dm_digtable.backoff_val = - dm_digtable.backoff_val_range_max; - else - dm_digtable.backoff_val += 2; - } - - if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) > - dm_digtable.rx_gain_range_max) - dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max; - else if ((dm_digtable.rssi_val_min + 10 - - dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) - dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min; - else - dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 - - dm_digtable.backoff_val; - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("rssi_val_min = %x backoff_val %x\n", - dm_digtable.rssi_val_min, dm_digtable.backoff_val)); - - rtl92c_dm_write_dig(hw); -} - -static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) -{ - static u8 binitialized; /* initialized to false */ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - bool b_multi_sta = false; - - if (mac->opmode == NL80211_IFTYPE_ADHOC) - b_multi_sta = true; - - if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate != - DIG_STA_DISCONNECT)) { - binitialized = false; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - return; - } else if (binitialized == false) { - binitialized = true; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable.cur_igvalue = 0x20; - rtl92c_dm_write_dig(hw); - } - - if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) { - if ((rssi_strength < dm_digtable.rssi_lowthresh) && - (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { - - if (dm_digtable.dig_ext_port_stage == - DIG_EXT_PORT_STAGE_2) { - dm_digtable.cur_igvalue = 0x20; - rtl92c_dm_write_dig(hw); - } - - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; - } else if (rssi_strength > dm_digtable.rssi_highthresh) { - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; - rtl92c_dm_ctrl_initgain_by_fa(hw); - } - } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable.cur_igvalue = 0x20; - rtl92c_dm_write_dig(hw); - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("curmultista_connectstate = " - "%x dig_ext_port_stage %x\n", - dm_digtable.curmultista_connectstate, - dm_digtable.dig_ext_port_stage)); -} - -static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("presta_connectstate = %x," - " cursta_connectctate = %x\n", - dm_digtable.presta_connectstate, - dm_digtable.cursta_connectctate)); - - if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate - || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT - || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { - - if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { - dm_digtable.rssi_val_min = - rtl92c_dm_initial_gain_min_pwdb(hw); - rtl92c_dm_ctrl_initgain_by_rssi(hw); - } - } else { - dm_digtable.rssi_val_min = 0; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable.cur_igvalue = 0x20; - dm_digtable.pre_igvalue = 0; - rtl92c_dm_write_dig(hw); - } -} - -static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { - dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); - - if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (dm_digtable.rssi_val_min <= 25) - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } else { - if (dm_digtable.rssi_val_min <= 20) - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } - } else { - dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; - } - - if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { - if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) - dm_digtable.cur_cck_fa_state = - CCK_FA_STAGE_High; - else - dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low; - - if (dm_digtable.pre_cck_fa_state != - dm_digtable.cur_cck_fa_state) { - if (dm_digtable.cur_cck_fa_state == - CCK_FA_STAGE_Low) - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0x83); - else - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0xcd); - - dm_digtable.pre_cck_fa_state = - dm_digtable.cur_cck_fa_state; - } - - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); - - if (IS_92C_SERIAL(rtlhal->version)) - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, - MASKBYTE2, 0xd7); - } else { - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); - - if (IS_92C_SERIAL(rtlhal->version)) - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, - MASKBYTE2, 0xd3); - } - dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); -} - -static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - - if (mac->act_scanning == true) - return; - - if ((mac->link_state > MAC80211_NOLINK) && - (mac->link_state < MAC80211_LINKED)) - dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; - else if (mac->link_state >= MAC80211_LINKED) - dm_digtable.cursta_connectctate = DIG_STA_CONNECT; - else - dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; - - rtl92c_dm_initial_gain_sta(hw); - rtl92c_dm_initial_gain_multi_sta(hw); - rtl92c_dm_cck_packet_detection_thresh(hw); - - dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate; - -} - -static void rtl92c_dm_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->dm.b_dm_initialgain_enable == false) - return; - if (dm_digtable.dig_enable_flag == false) - return; - - rtl92c_dm_ctrl_initgain_by_twoport(hw); - -} - -static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.bdynamic_txpower_enable = false; - - rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; -} - -void rtl92c_dm_write_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, backoff_val = %d\n", - dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, - dm_digtable.backoff_val)); - - if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { - rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, - dm_digtable.cur_igvalue); - rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, - dm_digtable.cur_igvalue); - - dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; - } -} - -static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; - - u8 h2c_parameter[3] = { 0 }; - - return; - - if (tmpentry_max_pwdb != 0) { - rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = - tmpentry_max_pwdb; - } else { - rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; - } - - if (tmpentry_min_pwdb != 0xff) { - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = - tmpentry_min_pwdb; - } else { - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; - } - - h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); - h2c_parameter[0] = 0; - - rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); -} - -void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - rtlpriv->dm.bcurrent_turbo_edca = false; - rtlpriv->dm.bis_any_nonbepkts = false; - rtlpriv->dm.bis_cur_rdlstate = false; -} - -static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - static u64 last_txok_cnt; - static u64 last_rxok_cnt; - u64 cur_txok_cnt; - u64 cur_rxok_cnt; - u32 edca_be_ul = 0x5ea42b; - u32 edca_be_dl = 0x5ea42b; - - if (mac->opmode == NL80211_IFTYPE_ADHOC) - goto dm_checkedcaturbo_exit; - - if (mac->link_state != MAC80211_LINKED) { - rtlpriv->dm.bcurrent_turbo_edca = false; - return; - } - - if (!mac->ht_enable) { /*FIX MERGE */ - if (!(edca_be_ul & 0xffff0000)) - edca_be_ul |= 0x005e0000; - - if (!(edca_be_dl & 0xffff0000)) - edca_be_dl |= 0x005e0000; - } - - if ((!rtlpriv->dm.bis_any_nonbepkts) && - (!rtlpriv->dm.b_disable_framebursting)) { - cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; - cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; - if (cur_rxok_cnt > 4 * cur_txok_cnt) { - if (!rtlpriv->dm.bis_cur_rdlstate || - !rtlpriv->dm.bcurrent_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_dl); - rtlpriv->dm.bis_cur_rdlstate = true; - } - } else { - if (rtlpriv->dm.bis_cur_rdlstate || - !rtlpriv->dm.bcurrent_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_ul); - rtlpriv->dm.bis_cur_rdlstate = false; - } - } - rtlpriv->dm.bcurrent_turbo_edca = true; - } else { - if (rtlpriv->dm.bcurrent_turbo_edca) { - u8 tmp = AC0_BE; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_AC_PARAM, - (u8 *) (&tmp)); - rtlpriv->dm.bcurrent_turbo_edca = false; - } - } - -dm_checkedcaturbo_exit: - rtlpriv->dm.bis_any_nonbepkts = false; - last_txok_cnt = rtlpriv->stats.txbytesunicast; - last_rxok_cnt = rtlpriv->stats.rxbytesunicast; -} - -static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw - *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 thermalvalue, delta, delta_lck, delta_iqk; - long ele_a, ele_d, temp_cck, val_x, value32; - long val_y, ele_c; - u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; - int i; - bool is2t = IS_92C_SERIAL(rtlhal->version); - u8 txpwr_level[2] = {0, 0}; - u8 ofdm_min_index = 6, rf; - - rtlpriv->dm.btxpower_trackingInit = true; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); - - thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter)); - - rtl92c_phy_ap_calibrate(hw, (thermalvalue - - rtlefuse->eeprom_thermalmeter)); - if (is2t) - rf = 2; - else - rf = 1; - - if (thermalvalue) { - ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD) & MASKOFDM_D; - - for (i = 0; i < OFDM_TABLE_LENGTH; i++) { - if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { - ofdm_index_old[0] = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathA ele_d reg0x%x = 0x%lx, " - "ofdm_index=0x%x\n", - ROFDM0_XATXIQIMBALANCE, - ele_d, ofdm_index_old[0])); - break; - } - } - - if (is2t) { - ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, - MASKDWORD) & MASKOFDM_D; - - for (i = 0; i < OFDM_TABLE_LENGTH; i++) { - if (ele_d == (ofdmswing_table[i] & - MASKOFDM_D)) { - ofdm_index_old[1] = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial pathB ele_d reg0x%x = " - "0x%lx, ofdm_index=0x%x\n", - ROFDM0_XBTXIQIMBALANCE, ele_d, - ofdm_index_old[1])); - break; - } - } - } - - temp_cck = - rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; - - for (i = 0; i < CCK_TABLE_LENGTH; i++) { - if (rtlpriv->dm.b_cck_inch14) { - if (memcmp((void *)&temp_cck, - (void *)&cckswing_table_ch14[i][2], - 4) == 0) { - cck_index_old = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch 14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.b_cck_inch14)); - break; - } - } else { - if (memcmp((void *)&temp_cck, - (void *) - &cckswing_table_ch1ch13[i][2], - 4) == 0) { - cck_index_old = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.b_cck_inch14)); - break; - } - } - } - - if (!rtlpriv->dm.thermalvalue) { - rtlpriv->dm.thermalvalue = - rtlefuse->eeprom_thermalmeter; - rtlpriv->dm.thermalvalue_lck = thermalvalue; - rtlpriv->dm.thermalvalue_iqk = thermalvalue; - for (i = 0; i < rf; i++) - rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; - rtlpriv->dm.cck_index = cck_index_old; - } - - delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? - (thermalvalue - rtlpriv->dm.thermalvalue) : - (rtlpriv->dm.thermalvalue - thermalvalue); - - delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? - (thermalvalue - rtlpriv->dm.thermalvalue_lck) : - (rtlpriv->dm.thermalvalue_lck - thermalvalue); - - delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? - (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : - (rtlpriv->dm.thermalvalue_iqk - thermalvalue); - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x delta 0x%x " - "delta_lck 0x%x delta_iqk 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter, delta, delta_lck, - delta_iqk)); - - if (delta_lck > 1) { - rtlpriv->dm.thermalvalue_lck = thermalvalue; - rtl92c_phy_lc_calibrate(hw); - } - - if (delta > 0 && rtlpriv->dm.txpower_track_control) { - if (thermalvalue > rtlpriv->dm.thermalvalue) { - for (i = 0; i < rf; i++) - rtlpriv->dm.ofdm_index[i] -= delta; - rtlpriv->dm.cck_index -= delta; - } else { - for (i = 0; i < rf; i++) - rtlpriv->dm.ofdm_index[i] += delta; - rtlpriv->dm.cck_index += delta; - } - - if (is2t) { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.ofdm_index[1], - rtlpriv->dm.cck_index)); - } else { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.cck_index)); - } - - if (thermalvalue > rtlefuse->eeprom_thermalmeter) { - for (i = 0; i < rf; i++) - ofdm_index[i] = - rtlpriv->dm.ofdm_index[i] - + 1; - cck_index = rtlpriv->dm.cck_index + 1; - } else { - for (i = 0; i < rf; i++) - ofdm_index[i] = - rtlpriv->dm.ofdm_index[i]; - cck_index = rtlpriv->dm.cck_index; - } - - for (i = 0; i < rf; i++) { - if (txpwr_level[i] >= 0 && - txpwr_level[i] <= 26) { - if (thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - ofdm_index[i] -= 1; - - else - ofdm_index[i] -= 2; - } else if (delta > 5 && thermalvalue < - rtlefuse-> - eeprom_thermalmeter) { - ofdm_index[i] += 1; - } - } else if (txpwr_level[i] >= 27 && - txpwr_level[i] <= 32 - && thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - ofdm_index[i] -= 1; - - else - ofdm_index[i] -= 2; - } else if (txpwr_level[i] >= 32 && - txpwr_level[i] <= 38 && - thermalvalue > - rtlefuse->eeprom_thermalmeter - && delta > 5) { - ofdm_index[i] -= 1; - } - } - - if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { - if (thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - cck_index -= 1; - - else - cck_index -= 2; - } else if (delta > 5 && thermalvalue < - rtlefuse->eeprom_thermalmeter) { - cck_index += 1; - } - } else if (txpwr_level[i] >= 27 && - txpwr_level[i] <= 32 && - thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - cck_index -= 1; - - else - cck_index -= 2; - } else if (txpwr_level[i] >= 32 && - txpwr_level[i] <= 38 && - thermalvalue > rtlefuse->eeprom_thermalmeter - && delta > 5) { - cck_index -= 1; - } - - for (i = 0; i < rf; i++) { - if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) - ofdm_index[i] = OFDM_TABLE_SIZE - 1; - - else if (ofdm_index[i] < ofdm_min_index) - ofdm_index[i] = ofdm_min_index; - } - - if (cck_index > CCK_TABLE_SIZE - 1) - cck_index = CCK_TABLE_SIZE - 1; - else if (cck_index < 0) - cck_index = 0; - - if (is2t) { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], ofdm_index[1], - cck_index)); - } else { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], cck_index)); - } - } - - if (rtlpriv->dm.txpower_track_control && delta != 0) { - ele_d = - (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; - val_x = rtlphy->reg_e94; - val_y = rtlphy->reg_e9c; - - if (val_x != 0) { - if ((val_x & 0x00000200) != 0) - val_x = val_x | 0xFFFFFC00; - ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; - - if ((val_y & 0x00000200) != 0) - val_y = val_y | 0xFFFFFC00; - ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; - - value32 = (ele_d << 22) | - ((ele_c & 0x3F) << 16) | ele_a; - - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD, value32); - - value32 = (ele_c & 0x000003C0) >> 6; - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, - value32); - - value32 = ((val_x * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(31), value32); - - value32 = ((val_y * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(29), value32); - } else { - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD, - ofdmswing_table[ofdm_index[0]]); - - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, - 0x00); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(31) | BIT(29), 0x00); - } - - if (!rtlpriv->dm.b_cck_inch14) { - rtl_write_byte(rtlpriv, 0xa22, - cckswing_table_ch1ch13[cck_index] - [0]); - rtl_write_byte(rtlpriv, 0xa23, - cckswing_table_ch1ch13[cck_index] - [1]); - rtl_write_byte(rtlpriv, 0xa24, - cckswing_table_ch1ch13[cck_index] - [2]); - rtl_write_byte(rtlpriv, 0xa25, - cckswing_table_ch1ch13[cck_index] - [3]); - rtl_write_byte(rtlpriv, 0xa26, - cckswing_table_ch1ch13[cck_index] - [4]); - rtl_write_byte(rtlpriv, 0xa27, - cckswing_table_ch1ch13[cck_index] - [5]); - rtl_write_byte(rtlpriv, 0xa28, - cckswing_table_ch1ch13[cck_index] - [6]); - rtl_write_byte(rtlpriv, 0xa29, - cckswing_table_ch1ch13[cck_index] - [7]); - } else { - rtl_write_byte(rtlpriv, 0xa22, - cckswing_table_ch14[cck_index] - [0]); - rtl_write_byte(rtlpriv, 0xa23, - cckswing_table_ch14[cck_index] - [1]); - rtl_write_byte(rtlpriv, 0xa24, - cckswing_table_ch14[cck_index] - [2]); - rtl_write_byte(rtlpriv, 0xa25, - cckswing_table_ch14[cck_index] - [3]); - rtl_write_byte(rtlpriv, 0xa26, - cckswing_table_ch14[cck_index] - [4]); - rtl_write_byte(rtlpriv, 0xa27, - cckswing_table_ch14[cck_index] - [5]); - rtl_write_byte(rtlpriv, 0xa28, - cckswing_table_ch14[cck_index] - [6]); - rtl_write_byte(rtlpriv, 0xa29, - cckswing_table_ch14[cck_index] - [7]); - } - - if (is2t) { - ele_d = (ofdmswing_table[ofdm_index[1]] & - 0xFFC00000) >> 22; - - val_x = rtlphy->reg_eb4; - val_y = rtlphy->reg_ebc; - - if (val_x != 0) { - if ((val_x & 0x00000200) != 0) - val_x = val_x | 0xFFFFFC00; - ele_a = ((val_x * ele_d) >> 8) & - 0x000003FF; - - if ((val_y & 0x00000200) != 0) - val_y = val_y | 0xFFFFFC00; - ele_c = ((val_y * ele_d) >> 8) & - 0x00003FF; - - value32 = (ele_d << 22) | - ((ele_c & 0x3F) << 16) | ele_a; - rtl_set_bbreg(hw, - ROFDM0_XBTXIQIMBALANCE, - MASKDWORD, value32); - - value32 = (ele_c & 0x000003C0) >> 6; - rtl_set_bbreg(hw, ROFDM0_XDTXAFE, - MASKH4BITS, value32); - - value32 = ((val_x * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(27), value32); - - value32 = ((val_y * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(25), value32); - } else { - rtl_set_bbreg(hw, - ROFDM0_XBTXIQIMBALANCE, - MASKDWORD, - ofdmswing_table[ofdm_index - [1]]); - rtl_set_bbreg(hw, ROFDM0_XDTXAFE, - MASKH4BITS, 0x00); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(27) | BIT(25), 0x00); - } - - } - } - - if (delta_iqk > 3) { - rtlpriv->dm.thermalvalue_iqk = thermalvalue; - rtl92c_phy_iq_calibrate(hw, false); - } - - if (rtlpriv->dm.txpower_track_control) - rtlpriv->dm.thermalvalue = thermalvalue; - } - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); - -} - -static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( - struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.btxpower_tracking = true; - rtlpriv->dm.btxpower_trackingInit = false; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->btxpower_tracking = %d\n", - rtlpriv->dm.btxpower_tracking)); -} - -static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) -{ - rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); -} - -static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) -{ - rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); -} - -static void rtl92c_dm_check_txpower_tracking_thermal_meter( - struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - static u8 tm_trigger; - - if (!rtlpriv->dm.btxpower_tracking) - return; - - if (!tm_trigger) { - rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, - 0x60); - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Trigger 92S Thermal Meter!!\n")); - tm_trigger = 1; - return; - } else { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Schedule TxPowerTracking direct call!!\n")); - rtl92c_dm_txpower_tracking_directcall(hw); - tm_trigger = 0; - } -} - -void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) -{ - rtl92c_dm_check_txpower_tracking_thermal_meter(hw); -} - -void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rate_adaptive *p_ra = &(rtlpriv->ra); - - p_ra->ratr_state = DM_RATR_STA_INIT; - p_ra->pre_ratr_state = DM_RATR_STA_INIT; - - if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) - rtlpriv->dm.b_useramask = true; - else - rtlpriv->dm.b_useramask = false; - -} - -static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rate_adaptive *p_ra = &(rtlpriv->ra); - u32 low_rssithresh_for_ra, high_rssithresh_for_ra; - - if (is_hal_stop(rtlhal)) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver is going to unload\n")); - return; - } - - if (!rtlpriv->dm.b_useramask) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver does not control rate adaptive mask\n")); - return; - } - - if (mac->link_state == MAC80211_LINKED) { - - switch (p_ra->pre_ratr_state) { - case DM_RATR_STA_HIGH: - high_rssithresh_for_ra = 50; - low_rssithresh_for_ra = 20; - break; - case DM_RATR_STA_MIDDLE: - high_rssithresh_for_ra = 55; - low_rssithresh_for_ra = 20; - break; - case DM_RATR_STA_LOW: - high_rssithresh_for_ra = 50; - low_rssithresh_for_ra = 25; - break; - default: - high_rssithresh_for_ra = 50; - low_rssithresh_for_ra = 20; - break; - } - - if (rtlpriv->dm.undecorated_smoothed_pwdb > - (long)high_rssithresh_for_ra) - p_ra->ratr_state = DM_RATR_STA_HIGH; - else if (rtlpriv->dm.undecorated_smoothed_pwdb > - (long)low_rssithresh_for_ra) - p_ra->ratr_state = DM_RATR_STA_MIDDLE; - else - p_ra->ratr_state = DM_RATR_STA_LOW; - - if (p_ra->pre_ratr_state != p_ra->ratr_state) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI = %ld\n", - rtlpriv->dm.undecorated_smoothed_pwdb)); - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("PreState = %d, CurState = %d\n", - p_ra->pre_ratr_state, p_ra->ratr_state)); - - rtlpriv->cfg->ops->update_rate_mask(hw, - p_ra->ratr_state); - - p_ra->pre_ratr_state = p_ra->ratr_state; - } - } -} - -static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) -{ - dm_pstable.pre_ccastate = CCA_MAX; - dm_pstable.cur_ccasate = CCA_MAX; - dm_pstable.pre_rfstate = RF_MAX; - dm_pstable.cur_rfstate = RF_MAX; - dm_pstable.rssi_val_min = 0; -} - -static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (dm_pstable.rssi_val_min != 0) { - if (dm_pstable.pre_ccastate == CCA_2R) { - if (dm_pstable.rssi_val_min >= 35) - dm_pstable.cur_ccasate = CCA_1R; - else - dm_pstable.cur_ccasate = CCA_2R; - } else { - if (dm_pstable.rssi_val_min <= 30) - dm_pstable.cur_ccasate = CCA_2R; - else - dm_pstable.cur_ccasate = CCA_1R; - } - } else { - dm_pstable.cur_ccasate = CCA_MAX; - } - - if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { - if (dm_pstable.cur_ccasate == CCA_1R) { - if (get_rf_type(rtlphy) == RF_2T2R) { - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, - MASKBYTE0, 0x13); - rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); - } else { - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, - MASKBYTE0, 0x23); - rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); - } - } else { - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, - 0x33); - rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); - } - dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; - } - - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", - (dm_pstable.cur_ccasate == - 0) ? "1RCCA" : "2RCCA")); -} - -void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) -{ - static u8 initialize; - static u32 reg_874, reg_c70, reg_85c, reg_a74; - - if (initialize == 0) { - reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - MASKDWORD) & 0x1CC000) >> 14; - - reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, - MASKDWORD) & BIT(3)) >> 3; - - reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - MASKDWORD) & 0xFF000000) >> 24; - - reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; - - initialize = 1; - } - - if (!bforce_in_normal) { - if (dm_pstable.rssi_val_min != 0) { - if (dm_pstable.pre_rfstate == RF_NORMAL) { - if (dm_pstable.rssi_val_min >= 30) - dm_pstable.cur_rfstate = RF_SAVE; - else - dm_pstable.cur_rfstate = RF_NORMAL; - } else { - if (dm_pstable.rssi_val_min <= 25) - dm_pstable.cur_rfstate = RF_NORMAL; - else - dm_pstable.cur_rfstate = RF_SAVE; - } - } else { - dm_pstable.cur_rfstate = RF_MAX; - } - } else { - dm_pstable.cur_rfstate = RF_NORMAL; - } - - if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) { - if (dm_pstable.cur_rfstate == RF_SAVE) { - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1C0000, 0x2); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - 0xFF000000, 0x63); - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0xC000, 0x2); - rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); - } else { - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1CC000, reg_874); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), - reg_c70); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, - reg_85c); - rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - } - - dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; - } -} - -static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (((mac->link_state == MAC80211_NOLINK)) && - (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { - dm_pstable.rssi_val_min = 0; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("Not connected to any\n")); - } - - if (mac->link_state == MAC80211_LINKED) { - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - dm_pstable.rssi_val_min = - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); - } else { - dm_pstable.rssi_val_min = - rtlpriv->dm.undecorated_smoothed_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); - } - } else { - dm_pstable.rssi_val_min = - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); - } - - if (IS_92C_SERIAL(rtlhal->version)) - rtl92c_dm_1r_cca(hw); -} - -void rtl92c_dm_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; - rtl92c_dm_diginit(hw); - rtl92c_dm_init_dynamic_txpower(hw); - rtl92c_dm_init_edca_turbo(hw); - rtl92c_dm_init_rate_adaptive_mask(hw); - rtl92c_dm_initialize_txpower_tracking(hw); - rtl92c_dm_init_dynamic_bb_powersaving(hw); -} - -void rtl92c_dm_watchdog(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool b_fw_current_inpsmode = false; - bool b_fw_ps_awake = true; - - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *) (&b_fw_current_inpsmode)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, - (u8 *) (&b_fw_ps_awake)); - - if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) && - b_fw_ps_awake) - && (!ppsc->rfchange_inprogress)) { - rtl92c_dm_pwdb_monitor(hw); - rtl92c_dm_dig(hw); - rtl92c_dm_false_alarm_counter_statistics(hw); - rtl92c_dm_dynamic_bb_powersaving(hw); - rtl92c_dm_dynamic_txpower(hw); - rtl92c_dm_check_txpower_tracking(hw); - rtl92c_dm_refresh_rate_adaptive_mask(hw); - rtl92c_dm_check_edca_turbo(hw); - } -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index ddf0a41a7a81..62e7c64e087b 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -35,9 +35,478 @@ #include "dm.h" #include "fw.h" -#include "../rtl8192c/dm_common.c" +struct dig_t dm_digtable; +static struct ps_t dm_pstable; -void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { + 0x7f8001fe, + 0x788001e2, + 0x71c001c7, + 0x6b8001ae, + 0x65400195, + 0x5fc0017f, + 0x5a400169, + 0x55400155, + 0x50800142, + 0x4c000130, + 0x47c0011f, + 0x43c0010f, + 0x40000100, + 0x3c8000f2, + 0x390000e4, + 0x35c000d7, + 0x32c000cb, + 0x300000c0, + 0x2d4000b5, + 0x2ac000ab, + 0x288000a2, + 0x26000098, + 0x24000090, + 0x22000088, + 0x20000080, + 0x1e400079, + 0x1c800072, + 0x1b00006c, + 0x19800066, + 0x18000060, + 0x16c0005b, + 0x15800056, + 0x14400051, + 0x1300004c, + 0x12000048, + 0x11000044, + 0x10000040, +}; + +static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} +}; + +static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} +}; + +static void rtl92c_dm_diginit(struct ieee80211_hw *hw) +{ + dm_digtable.dig_enable_flag = true; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.cur_igvalue = 0x20; + dm_digtable.pre_igvalue = 0x0; + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; + dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; + dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; + dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; + dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; + dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; + dm_digtable.rx_gain_range_max = DM_DIG_MAX; + dm_digtable.rx_gain_range_min = DM_DIG_MIN; + dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; + dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; + dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX; + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; +} + +static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long rssi_val_min = 0; + + if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) && + (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) + rssi_val_min = + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > + rtlpriv->dm.undecorated_smoothed_pwdb) ? + rtlpriv->dm.undecorated_smoothed_pwdb : + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + else + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT || + dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable.curmultista_connectstate == + DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + } + + return (u8) rssi_val_min; +} + +static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; + + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail); + + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " + "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); +} + +static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value_igi = dm_digtable.cur_igvalue; + + if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + value_igi--; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) + value_igi += 0; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) + value_igi++; + else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) + value_igi += 2; + if (value_igi > DM_DIG_FA_UPPER) + value_igi = DM_DIG_FA_UPPER; + else if (value_igi < DM_DIG_FA_LOWER) + value_igi = DM_DIG_FA_LOWER; + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + value_igi = 0x32; + + dm_digtable.cur_igvalue = value_igi; + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) { + if ((dm_digtable.backoff_val - 2) < + dm_digtable.backoff_val_range_min) + dm_digtable.backoff_val = + dm_digtable.backoff_val_range_min; + else + dm_digtable.backoff_val -= 2; + } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) { + if ((dm_digtable.backoff_val + 2) > + dm_digtable.backoff_val_range_max) + dm_digtable.backoff_val = + dm_digtable.backoff_val_range_max; + else + dm_digtable.backoff_val += 2; + } + + if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) > + dm_digtable.rx_gain_range_max) + dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max; + else if ((dm_digtable.rssi_val_min + 10 - + dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) + dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min; + else + dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 - + dm_digtable.backoff_val; + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("rssi_val_min = %x backoff_val %x\n", + dm_digtable.rssi_val_min, dm_digtable.backoff_val)); + + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) +{ + static u8 binitialized; /* initialized to false */ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + bool b_multi_sta = false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + b_multi_sta = true; + + if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate != + DIG_STA_DISCONNECT)) { + binitialized = false; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + return; + } else if (binitialized == false) { + binitialized = true; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) { + if ((rssi_strength < dm_digtable.rssi_lowthresh) && + (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { + + if (dm_digtable.dig_ext_port_stage == + DIG_EXT_PORT_STAGE_2) { + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; + } else if (rssi_strength > dm_digtable.rssi_highthresh) { + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; + rtl92c_dm_ctrl_initgain_by_fa(hw); + } + } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("curmultista_connectstate = " + "%x dig_ext_port_stage %x\n", + dm_digtable.curmultista_connectstate, + dm_digtable.dig_ext_port_stage)); +} + +static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("presta_connectstate = %x," + " cursta_connectctate = %x\n", + dm_digtable.presta_connectstate, + dm_digtable.cursta_connectctate)); + + if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate + || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT + || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { + + if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { + dm_digtable.rssi_val_min = + rtl92c_dm_initial_gain_min_pwdb(hw); + rtl92c_dm_ctrl_initgain_by_rssi(hw); + } + } else { + dm_digtable.rssi_val_min = 0; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable.cur_igvalue = 0x20; + dm_digtable.pre_igvalue = 0; + rtl92c_dm_write_dig(hw); + } +} + +static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { + dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); + + if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { + if (dm_digtable.rssi_val_min <= 25) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LowRssi; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HighRssi; + } else { + if (dm_digtable.rssi_val_min <= 20) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LowRssi; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HighRssi; + } + } else { + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; + } + + if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { + if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) + dm_digtable.cur_cck_fa_state = + CCK_FA_STAGE_High; + else + dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low; + + if (dm_digtable.pre_cck_fa_state != + dm_digtable.cur_cck_fa_state) { + if (dm_digtable.cur_cck_fa_state == + CCK_FA_STAGE_Low) + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0x83); + else + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0xcd); + + dm_digtable.pre_cck_fa_state = + dm_digtable.cur_cck_fa_state; + } + + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, + MASKBYTE2, 0xd7); + } else { + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, + MASKBYTE2, 0xd3); + } + dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; + } + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); +} + +static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + if (mac->act_scanning == true) + return; + + if ((mac->link_state > MAC80211_NOLINK) && + (mac->link_state < MAC80211_LINKED)) + dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; + else if (mac->link_state >= MAC80211_LINKED) + dm_digtable.cursta_connectctate = DIG_STA_CONNECT; + else + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + + rtl92c_dm_initial_gain_sta(hw); + rtl92c_dm_initial_gain_multi_sta(hw); + rtl92c_dm_cck_packet_detection_thresh(hw); + + dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate; + +} + +static void rtl92c_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.b_dm_initialgain_enable == false) + return; + if (dm_digtable.dig_enable_flag == false) + return; + + rtl92c_dm_ctrl_initgain_by_twoport(hw); + +} + +static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.bdynamic_txpower_enable = false; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} + +static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -115,4 +584,890 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; } +void rtl92c_dm_write_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("cur_igvalue = 0x%x, " + "pre_igvalue = 0x%x, backoff_val = %d\n", + dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, + dm_digtable.backoff_val)); + + if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + + dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; + } +} + +static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; + + u8 h2c_parameter[3] = { 0 }; + + return; + + if (tmpentry_max_pwdb != 0) { + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = + tmpentry_max_pwdb; + } else { + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; + } + + if (tmpentry_min_pwdb != 0xff) { + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = + tmpentry_min_pwdb; + } else { + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; + } + + h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); + h2c_parameter[0] = 0; + + rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); +} + +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtlpriv->dm.bcurrent_turbo_edca = false; + rtlpriv->dm.bis_any_nonbepkts = false; + rtlpriv->dm.bis_cur_rdlstate = false; +} + +static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + u64 cur_txok_cnt; + u64 cur_rxok_cnt; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + goto dm_checkedcaturbo_exit; + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.bcurrent_turbo_edca = false; + return; + } + + if (!mac->ht_enable) { /*FIX MERGE */ + if (!(edca_be_ul & 0xffff0000)) + edca_be_ul |= 0x005e0000; + + if (!(edca_be_dl & 0xffff0000)) + edca_be_dl |= 0x005e0000; + } + + if ((!rtlpriv->dm.bis_any_nonbepkts) && + (!rtlpriv->dm.b_disable_framebursting)) { + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.bis_cur_rdlstate || + !rtlpriv->dm.bcurrent_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_dl); + rtlpriv->dm.bis_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.bis_cur_rdlstate || + !rtlpriv->dm.bcurrent_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_ul); + rtlpriv->dm.bis_cur_rdlstate = false; + } + } + rtlpriv->dm.bcurrent_turbo_edca = true; + } else { + if (rtlpriv->dm.bcurrent_turbo_edca) { + u8 tmp = AC0_BE; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *) (&tmp)); + rtlpriv->dm.bcurrent_turbo_edca = false; + } + } + +dm_checkedcaturbo_exit: + rtlpriv->dm.bis_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw + *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 thermalvalue, delta, delta_lck, delta_iqk; + long ele_a, ele_d, temp_cck, val_x, value32; + long val_y, ele_c; + u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; + int i; + bool is2t = IS_92C_SERIAL(rtlhal->version); + u8 txpwr_level[2] = {0, 0}; + u8 ofdm_min_index = 6, rf; + + rtlpriv->dm.btxpower_trackingInit = true; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); + + thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " + "eeprom_thermalmeter 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter)); + + rtl92c_phy_ap_calibrate(hw, (thermalvalue - + rtlefuse->eeprom_thermalmeter)); + if (is2t) + rf = 2; + else + rf = 1; + + if (thermalvalue) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[0] = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Initial pathA ele_d reg0x%x = 0x%lx, " + "ofdm_index=0x%x\n", + ROFDM0_XATXIQIMBALANCE, + ele_d, ofdm_index_old[0])); + break; + } + } + + if (is2t) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[1] = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial pathB ele_d reg0x%x = " + "0x%lx, ofdm_index=0x%x\n", + ROFDM0_XBTXIQIMBALANCE, ele_d, + ofdm_index_old[1])); + break; + } + } + } + + temp_cck = + rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; + + for (i = 0; i < CCK_TABLE_LENGTH; i++) { + if (rtlpriv->dm.b_cck_inch14) { + if (memcmp((void *)&temp_cck, + (void *)&cckswing_table_ch14[i][2], + 4) == 0) { + cck_index_old = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.b_cck_inch14)); + break; + } + } else { + if (memcmp((void *)&temp_cck, + (void *) + &cckswing_table_ch1ch13[i][2], + 4) == 0) { + cck_index_old = (u8) i; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index=0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.b_cck_inch14)); + break; + } + } + } + + if (!rtlpriv->dm.thermalvalue) { + rtlpriv->dm.thermalvalue = + rtlefuse->eeprom_thermalmeter; + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; + rtlpriv->dm.cck_index = cck_index_old; + } + + delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? + (thermalvalue - rtlpriv->dm.thermalvalue) : + (rtlpriv->dm.thermalvalue - thermalvalue); + + delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? + (thermalvalue - rtlpriv->dm.thermalvalue_lck) : + (rtlpriv->dm.thermalvalue_lck - thermalvalue); + + delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? + (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : + (rtlpriv->dm.thermalvalue_iqk - thermalvalue); + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " + "eeprom_thermalmeter 0x%x delta 0x%x " + "delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk)); + + if (delta_lck > 1) { + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtl92c_phy_lc_calibrate(hw); + } + + if (delta > 0 && rtlpriv->dm.txpower_track_control) { + if (thermalvalue > rtlpriv->dm.thermalvalue) { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] -= delta; + rtlpriv->dm.cck_index -= delta; + } else { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] += delta; + rtlpriv->dm.cck_index += delta; + } + + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x, " + "OFDM_B_index=0x%x," + "cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x," + "cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index)); + } + + if (thermalvalue > rtlefuse->eeprom_thermalmeter) { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i] + + 1; + cck_index = rtlpriv->dm.cck_index + 1; + } else { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i]; + cck_index = rtlpriv->dm.cck_index; + } + + for (i = 0; i < rf; i++) { + if (txpwr_level[i] >= 0 && + txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse-> + eeprom_thermalmeter) { + ofdm_index[i] += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 + && thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > + rtlefuse->eeprom_thermalmeter + && delta > 5) { + ofdm_index[i] -= 1; + } + } + + if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse->eeprom_thermalmeter) { + cck_index += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 && + thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > rtlefuse->eeprom_thermalmeter + && delta > 5) { + cck_index -= 1; + } + + for (i = 0; i < rf; i++) { + if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) + ofdm_index[i] = OFDM_TABLE_SIZE - 1; + + else if (ofdm_index[i] < ofdm_min_index) + ofdm_index[i] = ofdm_min_index; + } + + if (cck_index > CCK_TABLE_SIZE - 1) + cck_index = CCK_TABLE_SIZE - 1; + else if (cck_index < 0) + cck_index = 0; + + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x, " + "OFDM_B_index=0x%x," + "cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], + cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x," + "cck_index=0x%x\n", + ofdm_index[0], cck_index)); + } + } + + if (rtlpriv->dm.txpower_track_control && delta != 0) { + ele_d = + (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; + val_x = rtlphy->reg_e94; + val_y = rtlphy->reg_e9c; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(29), value32); + } else { + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index[0]]); + + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31) | BIT(29), 0x00); + } + + if (!rtlpriv->dm.b_cck_inch14) { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch1ch13[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch1ch13[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch1ch13[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch1ch13[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch1ch13[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch1ch13[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch1ch13[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch1ch13[cck_index] + [7]); + } else { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch14[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch14[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch14[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch14[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch14[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch14[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch14[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch14[cck_index] + [7]); + } + + if (is2t) { + ele_d = (ofdmswing_table[ofdm_index[1]] & + 0xFFC00000) >> 22; + + val_x = rtlphy->reg_eb4; + val_y = rtlphy->reg_ebc; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & + 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & + 0x00003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(25), value32); + } else { + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index + [1]]); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27) | BIT(25), 0x00); + } + + } + } + + if (delta_iqk > 3) { + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + rtl92c_phy_iq_calibrate(hw, false); + } + + if (rtlpriv->dm.txpower_track_control) + rtlpriv->dm.thermalvalue = thermalvalue; + } + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + +} + +static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.btxpower_tracking = true; + rtlpriv->dm.btxpower_trackingInit = false; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("pMgntInfo->btxpower_tracking = %d\n", + rtlpriv->dm.btxpower_tracking)); +} + +static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); +} + +static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) +{ + rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); +} + +static void rtl92c_dm_check_txpower_tracking_thermal_meter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + static u8 tm_trigger; + + if (!rtlpriv->dm.btxpower_tracking) + return; + + if (!tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, + 0x60); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Trigger 92S Thermal Meter!!\n")); + tm_trigger = 1; + return; + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Schedule TxPowerTracking direct call!!\n")); + rtl92c_dm_txpower_tracking_directcall(hw); + tm_trigger = 0; + } +} + +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_check_txpower_tracking_thermal_meter(hw); +} + +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &(rtlpriv->ra); + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.b_useramask = true; + else + rtlpriv->dm.b_useramask = false; + +} + +static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *p_ra = &(rtlpriv->ra); + u32 low_rssithresh_for_ra, high_rssithresh_for_ra; + + if (is_hal_stop(rtlhal)) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("<---- driver is going to unload\n")); + return; + } + + if (!rtlpriv->dm.b_useramask) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("<---- driver does not control rate adaptive mask\n")); + return; + } + + if (mac->link_state == MAC80211_LINKED) { + + switch (p_ra->pre_ratr_state) { + case DM_RATR_STA_HIGH: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_MIDDLE: + high_rssithresh_for_ra = 55; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_LOW: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 25; + break; + default: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + } + + if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)high_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_HIGH; + else if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)low_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_MIDDLE; + else + p_ra->ratr_state = DM_RATR_STA_LOW; + + if (p_ra->pre_ratr_state != p_ra->ratr_state) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("RSSI = %ld\n", + rtlpriv->dm.undecorated_smoothed_pwdb)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state)); + + rtlpriv->cfg->ops->update_rate_mask(hw, + p_ra->ratr_state); + + p_ra->pre_ratr_state = p_ra->ratr_state; + } + } +} + +static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + dm_pstable.pre_ccastate = CCA_MAX; + dm_pstable.cur_ccasate = CCA_MAX; + dm_pstable.pre_rfstate = RF_MAX; + dm_pstable.cur_rfstate = RF_MAX; + dm_pstable.rssi_val_min = 0; +} + +static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (dm_pstable.rssi_val_min != 0) { + if (dm_pstable.pre_ccastate == CCA_2R) { + if (dm_pstable.rssi_val_min >= 35) + dm_pstable.cur_ccasate = CCA_1R; + else + dm_pstable.cur_ccasate = CCA_2R; + } else { + if (dm_pstable.rssi_val_min <= 30) + dm_pstable.cur_ccasate = CCA_2R; + else + dm_pstable.cur_ccasate = CCA_1R; + } + } else { + dm_pstable.cur_ccasate = CCA_MAX; + } + + if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { + if (dm_pstable.cur_ccasate == CCA_1R) { + if (get_rf_type(rtlphy) == RF_2T2R) { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x13); + rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); + } else { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x23); + rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); + } + } else { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, + 0x33); + rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); + } + dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; + } + + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", + (dm_pstable.cur_ccasate == + 0) ? "1RCCA" : "2RCCA")); +} + +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) +{ + static u8 initialize; + static u32 reg_874, reg_c70, reg_85c, reg_a74; + + if (initialize == 0) { + reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + MASKDWORD) & 0x1CC000) >> 14; + + reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, + MASKDWORD) & BIT(3)) >> 3; + + reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + MASKDWORD) & 0xFF000000) >> 24; + + reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; + + initialize = 1; + } + + if (!bforce_in_normal) { + if (dm_pstable.rssi_val_min != 0) { + if (dm_pstable.pre_rfstate == RF_NORMAL) { + if (dm_pstable.rssi_val_min >= 30) + dm_pstable.cur_rfstate = RF_SAVE; + else + dm_pstable.cur_rfstate = RF_NORMAL; + } else { + if (dm_pstable.rssi_val_min <= 25) + dm_pstable.cur_rfstate = RF_NORMAL; + else + dm_pstable.cur_rfstate = RF_SAVE; + } + } else { + dm_pstable.cur_rfstate = RF_MAX; + } + } else { + dm_pstable.cur_rfstate = RF_NORMAL; + } + + if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) { + if (dm_pstable.cur_rfstate == RF_SAVE) { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1C0000, 0x2); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + 0xFF000000, 0x63); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0xC000, 0x2); + rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); + } else { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1CC000, reg_874); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), + reg_c70); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, + reg_85c); + rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + } + + dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; + } +} + +static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (((mac->link_state == MAC80211_NOLINK)) && + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { + dm_pstable.rssi_val_min = 0; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("Not connected to any\n")); + } + + if (mac->link_state == MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + dm_pstable.rssi_val_min = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("AP Client PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } else { + dm_pstable.rssi_val_min = + rtlpriv->dm.undecorated_smoothed_pwdb; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("STA Default Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } + } else { + dm_pstable.rssi_val_min = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("AP Ext Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } + + if (IS_92C_SERIAL(rtlhal->version)) + rtl92c_dm_1r_cca(hw); +} + +void rtl92c_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl92c_dm_diginit(hw); + rtl92c_dm_init_dynamic_txpower(hw); + rtl92c_dm_init_edca_turbo(hw); + rtl92c_dm_init_rate_adaptive_mask(hw); + rtl92c_dm_initialize_txpower_tracking(hw); + rtl92c_dm_init_dynamic_bb_powersaving(hw); +} + +void rtl92c_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool b_fw_current_inpsmode = false; + bool b_fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *) (&b_fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *) (&b_fw_ps_awake)); + + if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) && + b_fw_ps_awake) + && (!ppsc->rfchange_inprogress)) { + rtl92c_dm_pwdb_monitor(hw); + rtl92c_dm_dig(hw); + rtl92c_dm_false_alarm_counter_statistics(hw); + rtl92c_dm_dynamic_bb_powersaving(hw); + rtl92c_dm_dynamic_txpower(hw); + rtl92c_dm_check_txpower_tracking(hw); + rtl92c_dm_refresh_rate_adaptive_mask(hw); + rtl92c_dm_check_edca_turbo(hw); + } +} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h index 5911d52a24ac..463439e4074c 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h @@ -192,6 +192,5 @@ void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); -void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); #endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c index b0776a34b817..11dd22b987e7 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c @@ -133,15 +133,17 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is_version_b; u8 *bufferPtr = (u8 *) buffer; RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); - if (IS_CHIP_VER_B(version)) { + is_version_b = IS_CHIP_VER_B(version); + if (is_version_b) { u32 pageNums, remainSize; u32 page, offset; - if (IS_HARDWARE_TYPE_8192CE(rtlhal)) + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) _rtl92c_fill_dummy(bufferPtr, &size); pageNums = size / FW_8192C_PAGE_SIZE; @@ -229,14 +231,14 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) u32 fwsize; int err; enum version_8192c version = rtlhal->version; - const struct firmware *firmware; - printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n", - rtlpriv->cfg->fw_name); + const struct firmware *firmware = NULL; + err = request_firmware(&firmware, rtlpriv->cfg->fw_name, rtlpriv->io.dev); if (err) { - printk(KERN_ERR "rtl8192cu: Firmware loading failed\n"); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to request firmware!\n")); return 1; } @@ -558,6 +560,39 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) } +static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + u8 own; + unsigned long flags; + struct sk_buff *pskb = NULL; + + ring = &rtlpci->tx_ring[BEACON_QUEUE]; + + pskb = __skb_dequeue(&ring->queue); + if (pskb) + kfree_skb(pskb); + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + + pdesc = &ring->desc[0]; + own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); + + rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); + + __skb_queue_tail(&ring->queue, skb); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); + + return true; +} + #define BEACON_PG 0 /*->1*/ #define PSPOLL_PG 2 #define NULL_PG 3 @@ -741,7 +776,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, totalpacketlen); - rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb); + rtstatus = _rtl92c_cmd_send_packet(hw, skb); if (rtstatus) b_dlok = true; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 05f7a45b30e1..45044117139a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -37,9 +37,6 @@ #include "dm.h" #include "table.h" -/* Define macro to shorten lines */ -#define MCS_TXPWR mcs_txpwrlevel_origoffset - static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset); static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, @@ -483,129 +480,161 @@ static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, struct rtl_phy *rtlphy = &(rtlpriv->phy); if (regaddr == RTXAGC_A_RATE18_06) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][0])); } if (regaddr == RTXAGC_A_RATE54_24) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][1])); } if (regaddr == RTXAGC_A_CCK1_MCS32) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][6])); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][7])); } if (regaddr == RTXAGC_A_MCS03_MCS00) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][2])); } if (regaddr == RTXAGC_A_MCS07_MCS04) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][3])); } if (regaddr == RTXAGC_A_MCS11_MCS08) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][4])); } if (regaddr == RTXAGC_A_MCS15_MCS12) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][5])); } if (regaddr == RTXAGC_B_RATE18_06) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][8])); } if (regaddr == RTXAGC_B_RATE54_24) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][9])); } if (regaddr == RTXAGC_B_CCK1_55_MCS32) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][14])); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][15])); } if (regaddr == RTXAGC_B_MCS03_MCS00) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][10])); } if (regaddr == RTXAGC_B_MCS07_MCS04) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][11])); } if (regaddr == RTXAGC_B_MCS11_MCS08) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][12])); } if (regaddr == RTXAGC_B_MCS15_MCS12) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = + data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> + pwrgroup_cnt][13])); rtlphy->pwrgroup_cnt++; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index a8b3d0605abd..b366e8862929 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -135,7 +135,6 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { .set_bbreg = rtl92c_phy_set_bb_reg, .get_rfreg = rtl92c_phy_query_rf_reg, .set_rfreg = rtl92c_phy_set_rf_reg, - .cmd_send_packet = _rtl92c_cmd_send_packet, }; static struct rtl_mod_params rtl92ce_mod_params = { diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h index 0568d6dc83d7..de1198c38d4e 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h @@ -33,7 +33,5 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw); void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); void rtl92c_init_var_map(struct ieee80211_hw *hw); -bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, - struct sk_buff *skb); #endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 003bf108193f..bf5852f2d634 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -1029,36 +1029,3 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) BIT(0) << (hw_queue)); } } - -bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, - struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl8192_tx_ring *ring; - struct rtl_tx_desc *pdesc; - u8 own; - unsigned long flags; - struct sk_buff *pskb = NULL; - - ring = &rtlpci->tx_ring[BEACON_QUEUE]; - - spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); - - pskb = __skb_dequeue(&ring->queue); - if (pskb) - kfree_skb(pskb); - - pdesc = &ring->desc[0]; - own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); - - rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); - - __skb_queue_tail(&ring->queue, skb); - - spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); - - rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); - - return true; -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index a5fcdfb69cda..53d0e0a5af5c 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -711,6 +711,4 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue); void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool b_firstseg, bool b_lastseg, struct sk_buff *skb); -bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); - #endif diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.c b/trunk/drivers/net/wireless/rtlwifi/usb.c deleted file mode 100644 index fbf24a0f9054..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/usb.c +++ /dev/null @@ -1,1035 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - *****************************************************************************/ -#include -#include "core.h" -#include "wifi.h" -#include "usb.h" -#include "base.h" -#include "ps.h" - -#define REALTEK_USB_VENQT_READ 0xC0 -#define REALTEK_USB_VENQT_WRITE 0x40 -#define REALTEK_USB_VENQT_CMD_REQ 0x05 -#define REALTEK_USB_VENQT_CMD_IDX 0x00 - -#define REALTEK_USB_VENQT_MAX_BUF_SIZE 254 - -static void usbctrl_async_callback(struct urb *urb) -{ - if (urb) - kfree(urb->context); -} - -static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, - u16 value, u16 index, void *pdata, - u16 len) -{ - int rc; - unsigned int pipe; - u8 reqtype; - struct usb_ctrlrequest *dr; - struct urb *urb; - struct rtl819x_async_write_data { - u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE]; - struct usb_ctrlrequest dr; - } *buf; - - pipe = usb_sndctrlpipe(udev, 0); /* write_out */ - reqtype = REALTEK_USB_VENQT_WRITE; - - buf = kmalloc(sizeof(*buf), GFP_ATOMIC); - if (!buf) - return -ENOMEM; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - kfree(buf); - return -ENOMEM; - } - - dr = &buf->dr; - - dr->bRequestType = reqtype; - dr->bRequest = request; - dr->wValue = cpu_to_le16(value); - dr->wIndex = cpu_to_le16(index); - dr->wLength = cpu_to_le16(len); - memcpy(buf, pdata, len); - usb_fill_control_urb(urb, udev, pipe, - (unsigned char *)dr, buf, len, - usbctrl_async_callback, buf); - rc = usb_submit_urb(urb, GFP_ATOMIC); - if (rc < 0) - kfree(buf); - usb_free_urb(urb); - return rc; -} - -static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request, - u16 value, u16 index, void *pdata, - u16 len) -{ - unsigned int pipe; - int status; - u8 reqtype; - - pipe = usb_rcvctrlpipe(udev, 0); /* read_in */ - reqtype = REALTEK_USB_VENQT_READ; - - status = usb_control_msg(udev, pipe, request, reqtype, value, index, - pdata, len, 0); /* max. timeout */ - - if (status < 0) - printk(KERN_ERR "reg 0x%x, usbctrl_vendorreq TimeOut! " - "status:0x%x value=0x%x\n", value, status, - *(u32 *)pdata); - return status; -} - -static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len) -{ - u8 request; - u16 wvalue; - u16 index; - u32 *data; - u32 ret; - - data = kmalloc(sizeof(u32), GFP_KERNEL); - if (!data) - return -ENOMEM; - request = REALTEK_USB_VENQT_CMD_REQ; - index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ - - wvalue = (u16)addr; - _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); - ret = le32_to_cpu(*data); - kfree(data); - return ret; -} - -static u8 _usb_read8_sync(struct rtl_priv *rtlpriv, u32 addr) -{ - struct device *dev = rtlpriv->io.dev; - - return (u8)_usb_read_sync(to_usb_device(dev), addr, 1); -} - -static u16 _usb_read16_sync(struct rtl_priv *rtlpriv, u32 addr) -{ - struct device *dev = rtlpriv->io.dev; - - return (u16)_usb_read_sync(to_usb_device(dev), addr, 2); -} - -static u32 _usb_read32_sync(struct rtl_priv *rtlpriv, u32 addr) -{ - struct device *dev = rtlpriv->io.dev; - - return _usb_read_sync(to_usb_device(dev), addr, 4); -} - -static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val, - u16 len) -{ - u8 request; - u16 wvalue; - u16 index; - u32 data; - - request = REALTEK_USB_VENQT_CMD_REQ; - index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ - wvalue = (u16)(addr&0x0000ffff); - data = cpu_to_le32(val); - _usbctrl_vendorreq_async_write(udev, request, wvalue, index, &data, - len); -} - -static void _usb_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) -{ - struct device *dev = rtlpriv->io.dev; - - _usb_write_async(to_usb_device(dev), addr, val, 1); -} - -static void _usb_write16_async(struct rtl_priv *rtlpriv, u32 addr, u16 val) -{ - struct device *dev = rtlpriv->io.dev; - - _usb_write_async(to_usb_device(dev), addr, val, 2); -} - -static void _usb_write32_async(struct rtl_priv *rtlpriv, u32 addr, u32 val) -{ - struct device *dev = rtlpriv->io.dev; - - _usb_write_async(to_usb_device(dev), addr, val, 4); -} - -static int _usb_nbytes_read_write(struct usb_device *udev, bool read, u32 addr, - u16 len, u8 *pdata) -{ - int status; - u8 request; - u16 wvalue; - u16 index; - - request = REALTEK_USB_VENQT_CMD_REQ; - index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ - wvalue = (u16)addr; - if (read) - status = _usbctrl_vendorreq_sync_read(udev, request, wvalue, - index, pdata, len); - else - status = _usbctrl_vendorreq_async_write(udev, request, wvalue, - index, pdata, len); - return status; -} - -static int _usb_readN_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len, - u8 *pdata) -{ - struct device *dev = rtlpriv->io.dev; - - return _usb_nbytes_read_write(to_usb_device(dev), true, addr, len, - pdata); -} - -static int _usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, u16 len, - u8 *pdata) -{ - struct device *dev = rtlpriv->io.dev; - - return _usb_nbytes_read_write(to_usb_device(dev), false, addr, len, - pdata); -} - -static void _rtl_usb_io_handler_init(struct device *dev, - struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->io.dev = dev; - mutex_init(&rtlpriv->io.bb_mutex); - rtlpriv->io.write8_async = _usb_write8_async; - rtlpriv->io.write16_async = _usb_write16_async; - rtlpriv->io.write32_async = _usb_write32_async; - rtlpriv->io.writeN_async = _usb_writeN_async; - rtlpriv->io.read8_sync = _usb_read8_sync; - rtlpriv->io.read16_sync = _usb_read16_sync; - rtlpriv->io.read32_sync = _usb_read32_sync; - rtlpriv->io.readN_sync = _usb_readN_sync; -} - -static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - mutex_destroy(&rtlpriv->io.bb_mutex); -} - -/** - * - * Default aggregation handler. Do nothing and just return the oldest skb. - */ -static struct sk_buff *_none_usb_tx_aggregate_hdl(struct ieee80211_hw *hw, - struct sk_buff_head *list) -{ - return skb_dequeue(list); -} - -#define IS_HIGH_SPEED_USB(udev) \ - ((USB_SPEED_HIGH == (udev)->speed) ? true : false) - -static int _rtl_usb_init_tx(struct ieee80211_hw *hw) -{ - u32 i; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - - rtlusb->max_bulk_out_size = IS_HIGH_SPEED_USB(rtlusb->udev) - ? USB_HIGH_SPEED_BULK_SIZE - : USB_FULL_SPEED_BULK_SIZE; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("USB Max Bulk-out Size=%d\n", - rtlusb->max_bulk_out_size)); - - for (i = 0; i < __RTL_TXQ_NUM; i++) { - u32 ep_num = rtlusb->ep_map.ep_mapping[i]; - if (!ep_num) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Invalid endpoint map setting!\n")); - return -EINVAL; - } - } - - rtlusb->usb_tx_post_hdl = - rtlpriv->cfg->usb_interface_cfg->usb_tx_post_hdl; - rtlusb->usb_tx_cleanup = - rtlpriv->cfg->usb_interface_cfg->usb_tx_cleanup; - rtlusb->usb_tx_aggregate_hdl = - (rtlpriv->cfg->usb_interface_cfg->usb_tx_aggregate_hdl) - ? rtlpriv->cfg->usb_interface_cfg->usb_tx_aggregate_hdl - : &_none_usb_tx_aggregate_hdl; - - init_usb_anchor(&rtlusb->tx_submitted); - for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { - skb_queue_head_init(&rtlusb->tx_skb_queue[i]); - init_usb_anchor(&rtlusb->tx_pending[i]); - } - return 0; -} - -static int _rtl_usb_init_rx(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); - struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); - - rtlusb->rx_max_size = rtlpriv->cfg->usb_interface_cfg->rx_max_size; - rtlusb->rx_urb_num = rtlpriv->cfg->usb_interface_cfg->rx_urb_num; - rtlusb->in_ep = rtlpriv->cfg->usb_interface_cfg->in_ep_num; - rtlusb->usb_rx_hdl = rtlpriv->cfg->usb_interface_cfg->usb_rx_hdl; - rtlusb->usb_rx_segregate_hdl = - rtlpriv->cfg->usb_interface_cfg->usb_rx_segregate_hdl; - - printk(KERN_INFO "rtl8192cu: rx_max_size %d, rx_urb_num %d, in_ep %d\n", - rtlusb->rx_max_size, rtlusb->rx_urb_num, rtlusb->in_ep); - init_usb_anchor(&rtlusb->rx_submitted); - return 0; -} - -static int _rtl_usb_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); - struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); - int err; - u8 epidx; - struct usb_interface *usb_intf = rtlusb->intf; - u8 epnums = usb_intf->cur_altsetting->desc.bNumEndpoints; - - rtlusb->out_ep_nums = rtlusb->in_ep_nums = 0; - for (epidx = 0; epidx < epnums; epidx++) { - struct usb_endpoint_descriptor *pep_desc; - pep_desc = &usb_intf->cur_altsetting->endpoint[epidx].desc; - - if (usb_endpoint_dir_in(pep_desc)) - rtlusb->in_ep_nums++; - else if (usb_endpoint_dir_out(pep_desc)) - rtlusb->out_ep_nums++; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB EP(0x%02x), MaxPacketSize=%d ,Interval=%d.\n", - pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, - pep_desc->bInterval)); - } - if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) - return -EINVAL ; - - /* usb endpoint mapping */ - err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); - rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; - _rtl_usb_init_tx(hw); - _rtl_usb_init_rx(hw); - return err; -} - -static int _rtl_usb_init_sw(struct ieee80211_hw *hw) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - - rtlhal->hw = hw; - ppsc->b_inactiveps = false; - ppsc->b_leisure_ps = false; - ppsc->b_fwctrl_lps = false; - ppsc->b_reg_fwctrl_lps = 3; - ppsc->reg_max_lps_awakeintvl = 5; - ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; - - /* IBSS */ - mac->beacon_interval = 100; - - /* AMPDU */ - mac->min_space_cfg = 0; - mac->max_mss_density = 0; - - /* set sane AMPDU defaults */ - mac->current_ampdu_density = 7; - mac->current_ampdu_factor = 3; - - /* QOS */ - rtlusb->acm_method = eAcmWay2_SW; - - /* IRQ */ - /* HIMR - turn all on */ - rtlusb->irq_mask[0] = 0xFFFFFFFF; - /* HIMR_EX - turn all on */ - rtlusb->irq_mask[1] = 0xFFFFFFFF; - rtlusb->disableHWSM = true; - return 0; -} - -#define __RADIO_TAP_SIZE_RSV 32 - -static void _rtl_rx_completed(struct urb *urb); - -static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, - struct rtl_usb *rtlusb, - struct urb *urb, - gfp_t gfp_mask) -{ - struct sk_buff *skb; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - skb = __dev_alloc_skb((rtlusb->rx_max_size + __RADIO_TAP_SIZE_RSV), - gfp_mask); - if (!skb) { - RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to __dev_alloc_skb!!\n")) - return ERR_PTR(-ENOMEM); - } - - /* reserve some space for mac80211's radiotap */ - skb_reserve(skb, __RADIO_TAP_SIZE_RSV); - usb_fill_bulk_urb(urb, rtlusb->udev, - usb_rcvbulkpipe(rtlusb->udev, rtlusb->in_ep), - skb->data, min(skb_tailroom(skb), - (int)rtlusb->rx_max_size), - _rtl_rx_completed, skb); - - _rtl_install_trx_info(rtlusb, skb, rtlusb->in_ep); - return skb; -} - -#undef __RADIO_TAP_SIZE_RSV - -static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, - struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 *rxdesc = skb->data; - struct ieee80211_hdr *hdr; - bool unicast = false; - u16 fc; - struct ieee80211_rx_status rx_status = {0}; - struct rtl_stats stats = { - .signal = 0, - .noise = -98, - .rate = 0, - }; - - skb_pull(skb, RTL_RX_DESC_SIZE); - rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); - skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); - hdr = (struct ieee80211_hdr *)(skb->data); - fc = le16_to_cpu(hdr->frame_control); - if (!stats.b_crc) { - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - - if (is_broadcast_ether_addr(hdr->addr1)) { - /*TODO*/; - } else if (is_multicast_ether_addr(hdr->addr1)) { - /*TODO*/ - } else { - unicast = true; - rtlpriv->stats.rxbytesunicast += skb->len; - } - - rtl_is_special_data(hw, skb, false); - - if (ieee80211_is_data(fc)) { - rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); - - if (unicast) - rtlpriv->link_info.num_rx_inperiod++; - } - } -} - -static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, - struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 *rxdesc = skb->data; - struct ieee80211_hdr *hdr; - bool unicast = false; - u16 fc; - struct ieee80211_rx_status rx_status = {0}; - struct rtl_stats stats = { - .signal = 0, - .noise = -98, - .rate = 0, - }; - - skb_pull(skb, RTL_RX_DESC_SIZE); - rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); - skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); - hdr = (struct ieee80211_hdr *)(skb->data); - fc = le16_to_cpu(hdr->frame_control); - if (!stats.b_crc) { - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - - if (is_broadcast_ether_addr(hdr->addr1)) { - /*TODO*/; - } else if (is_multicast_ether_addr(hdr->addr1)) { - /*TODO*/ - } else { - unicast = true; - rtlpriv->stats.rxbytesunicast += skb->len; - } - - rtl_is_special_data(hw, skb, false); - - if (ieee80211_is_data(fc)) { - rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); - - if (unicast) - rtlpriv->link_info.num_rx_inperiod++; - } - if (likely(rtl_action_proc(hw, skb, false))) { - struct sk_buff *uskb = NULL; - u8 *pdata; - - uskb = dev_alloc_skb(skb->len + 128); - memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, - sizeof(rx_status)); - pdata = (u8 *)skb_put(uskb, skb->len); - memcpy(pdata, skb->data, skb->len); - dev_kfree_skb_any(skb); - ieee80211_rx_irqsafe(hw, uskb); - } else { - dev_kfree_skb_any(skb); - } - } -} - -static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct sk_buff *_skb; - struct sk_buff_head rx_queue; - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - - skb_queue_head_init(&rx_queue); - if (rtlusb->usb_rx_segregate_hdl) - rtlusb->usb_rx_segregate_hdl(hw, skb, &rx_queue); - WARN_ON(skb_queue_empty(&rx_queue)); - while (!skb_queue_empty(&rx_queue)) { - _skb = skb_dequeue(&rx_queue); - _rtl_usb_rx_process_agg(hw, skb); - ieee80211_rx_irqsafe(hw, skb); - } -} - -static void _rtl_rx_completed(struct urb *_urb) -{ - struct sk_buff *skb = (struct sk_buff *)_urb->context; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0]; - struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); - struct rtl_priv *rtlpriv = rtl_priv(hw); - int err = 0; - - if (unlikely(IS_USB_STOP(rtlusb))) - goto free; - - if (likely(0 == _urb->status)) { - /* If this code were moved to work queue, would CPU - * utilization be improved? NOTE: We shall allocate another skb - * and reuse the original one. - */ - skb_put(skb, _urb->actual_length); - - if (likely(!rtlusb->usb_rx_segregate_hdl)) { - struct sk_buff *_skb; - _rtl_usb_rx_process_noagg(hw, skb); - _skb = _rtl_prep_rx_urb(hw, rtlusb, _urb, GFP_ATOMIC); - if (IS_ERR(_skb)) { - err = PTR_ERR(_skb); - RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate skb for bulk IN!\n")); - return; - } - skb = _skb; - } else{ - /* TO DO */ - _rtl_rx_pre_process(hw, skb); - printk(KERN_ERR "rtlwifi: rx agg not supported\n"); - } - goto resubmit; - } - - switch (_urb->status) { - /* disconnect */ - case -ENOENT: - case -ECONNRESET: - case -ENODEV: - case -ESHUTDOWN: - goto free; - default: - break; - } - -resubmit: - skb_reset_tail_pointer(skb); - skb_trim(skb, 0); - - usb_anchor_urb(_urb, &rtlusb->rx_submitted); - err = usb_submit_urb(_urb, GFP_ATOMIC); - if (unlikely(err)) { - usb_unanchor_urb(_urb); - goto free; - } - return; - -free: - dev_kfree_skb_irq(skb); -} - -static int _rtl_usb_receive(struct ieee80211_hw *hw) -{ - struct urb *urb; - struct sk_buff *skb; - int err; - int i; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - - WARN_ON(0 == rtlusb->rx_urb_num); - /* 1600 == 1514 + max WLAN header + rtk info */ - WARN_ON(rtlusb->rx_max_size < 1600); - - for (i = 0; i < rtlusb->rx_urb_num; i++) { - err = -ENOMEM; - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to alloc URB!!\n")) - goto err_out; - } - - skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); - if (IS_ERR(skb)) { - RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to prep_rx_urb!!\n")) - err = PTR_ERR(skb); - goto err_out; - } - - usb_anchor_urb(urb, &rtlusb->rx_submitted); - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) - goto err_out; - usb_free_urb(urb); - } - return 0; - -err_out: - usb_kill_anchored_urbs(&rtlusb->rx_submitted); - return err; -} - -static int rtl_usb_start(struct ieee80211_hw *hw) -{ - int err; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - - err = rtlpriv->cfg->ops->hw_init(hw); - rtl_init_rx_config(hw); - - /* Enable software */ - SET_USB_START(rtlusb); - /* should after adapter start and interrupt enable. */ - set_hal_start(rtlhal); - - /* Start bulk IN */ - _rtl_usb_receive(hw); - - return err; -} -/** - * - * - */ - -/*======================= tx =========================================*/ -static void rtl_usb_cleanup(struct ieee80211_hw *hw) -{ - u32 i; - struct sk_buff *_skb; - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - struct ieee80211_tx_info *txinfo; - - SET_USB_STOP(rtlusb); - - /* clean up rx stuff. */ - usb_kill_anchored_urbs(&rtlusb->rx_submitted); - - /* clean up tx stuff */ - for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { - while ((_skb = skb_dequeue(&rtlusb->tx_skb_queue[i]))) { - rtlusb->usb_tx_cleanup(hw, _skb); - txinfo = IEEE80211_SKB_CB(_skb); - ieee80211_tx_info_clear_status(txinfo); - txinfo->flags |= IEEE80211_TX_STAT_ACK; - ieee80211_tx_status_irqsafe(hw, _skb); - } - usb_kill_anchored_urbs(&rtlusb->tx_pending[i]); - } - usb_kill_anchored_urbs(&rtlusb->tx_submitted); -} - -/** - * - * We may add some struct into struct rtl_usb later. Do deinit here. - * - */ -static void rtl_usb_deinit(struct ieee80211_hw *hw) -{ - rtl_usb_cleanup(hw); -} - -static void rtl_usb_stop(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - - /* should after adapter start and interrupt enable. */ - set_hal_stop(rtlhal); - /* Enable software */ - SET_USB_STOP(rtlusb); - rtl_usb_deinit(hw); - rtlpriv->cfg->ops->hw_disable(hw); -} - -static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb) -{ - int err; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - - usb_anchor_urb(_urb, &rtlusb->tx_submitted); - err = usb_submit_urb(_urb, GFP_ATOMIC); - if (err < 0) { - struct sk_buff *skb; - - RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to submit urb.\n")); - usb_unanchor_urb(_urb); - skb = (struct sk_buff *)_urb->context; - kfree_skb(skb); - } - usb_free_urb(_urb); -} - -static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb, - struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - struct ieee80211_tx_info *txinfo; - - rtlusb->usb_tx_post_hdl(hw, urb, skb); - skb_pull(skb, RTL_TX_HEADER_SIZE); - txinfo = IEEE80211_SKB_CB(skb); - ieee80211_tx_info_clear_status(txinfo); - txinfo->flags |= IEEE80211_TX_STAT_ACK; - - if (urb->status) { - RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Urb has error status 0x%X\n", urb->status)); - goto out; - } - /* TODO: statistics */ -out: - ieee80211_tx_status_irqsafe(hw, skb); - return urb->status; -} - -static void _rtl_tx_complete(struct urb *urb) -{ - struct sk_buff *skb = (struct sk_buff *)urb->context; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0]; - struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); - int err; - - if (unlikely(IS_USB_STOP(rtlusb))) - return; - err = _usb_tx_post(hw, urb, skb); - if (err) { - /* Ignore error and keep issuiing other urbs */ - return; - } -} - -static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw, - struct sk_buff *skb, u32 ep_num) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - struct urb *_urb; - - WARN_ON(NULL == skb); - _urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!_urb) { - RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate URB for bulk out!\n")); - kfree_skb(skb); - return NULL; - } - _rtl_install_trx_info(rtlusb, skb, ep_num); - usb_fill_bulk_urb(_urb, rtlusb->udev, usb_sndbulkpipe(rtlusb->udev, - ep_num), skb->data, skb->len, _rtl_tx_complete, skb); - _urb->transfer_flags |= URB_ZERO_PACKET; - return _urb; -} - -static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, - enum rtl_txq qnum) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - u32 ep_num; - struct urb *_urb = NULL; - struct sk_buff *_skb = NULL; - struct sk_buff_head *skb_list; - struct usb_anchor *urb_list; - - WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); - if (unlikely(IS_USB_STOP(rtlusb))) { - RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("USB device is stopping...\n")); - kfree_skb(skb); - return; - } - ep_num = rtlusb->ep_map.ep_mapping[qnum]; - skb_list = &rtlusb->tx_skb_queue[ep_num]; - _skb = skb; - _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); - if (unlikely(!_urb)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate urb. Drop skb!\n")); - return; - } - urb_list = &rtlusb->tx_pending[ep_num]; - _rtl_submit_tx_urb(hw, _urb); -} - -static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, - u16 hw_queue) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct rtl_tx_desc *pdesc = NULL; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u16 fc = le16_to_cpu(hdr->frame_control); - u8 *pda_addr = hdr->addr1; - /* ssn */ - u8 *qc = NULL; - u8 tid = 0; - u16 seq_number = 0; - - if (ieee80211_is_mgmt(fc)) - rtl_tx_mgmt_proc(hw, skb); - rtl_action_proc(hw, skb, true); - if (is_multicast_ether_addr(pda_addr)) - rtlpriv->stats.txbytesmulticast += skb->len; - else if (is_broadcast_ether_addr(pda_addr)) - rtlpriv->stats.txbytesbroadcast += skb->len; - else - rtlpriv->stats.txbytesunicast += skb->len; - if (ieee80211_is_data_qos(fc)) { - qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; - seq_number = (le16_to_cpu(hdr->seq_ctrl) & - IEEE80211_SCTL_SEQ) >> 4; - seq_number += 1; - seq_number <<= 4; - } - rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb, - hw_queue); - if (!ieee80211_has_morefrags(hdr->frame_control)) { - if (qc) - mac->tids[tid].seq_number = seq_number; - } - if (ieee80211_is_data(fc)) - rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); -} - -static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u16 fc = le16_to_cpu(hdr->frame_control); - u16 hw_queue; - - if (unlikely(is_hal_stop(rtlhal))) - goto err_free; - hw_queue = rtlusb->usb_mq_to_hwq(fc, skb_get_queue_mapping(skb)); - _rtl_usb_tx_preprocess(hw, skb, hw_queue); - _rtl_usb_transmit(hw, skb, hw_queue); - return NETDEV_TX_OK; - -err_free: - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; -} - -static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw, - struct sk_buff *skb) -{ - return false; -} - -static struct rtl_intf_ops rtl_usb_ops = { - .adapter_start = rtl_usb_start, - .adapter_stop = rtl_usb_stop, - .adapter_tx = rtl_usb_tx, - .waitq_insert = rtl_usb_tx_chk_waitq_insert, -}; - -int __devinit rtl_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int err; - struct ieee80211_hw *hw = NULL; - struct rtl_priv *rtlpriv = NULL; - struct usb_device *udev; - struct rtl_usb_priv *usb_priv; - - hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + - sizeof(struct rtl_usb_priv), &rtl_ops); - if (!hw) { - RT_ASSERT(false, ("%s : ieee80211 alloc failed\n", __func__)); - return -ENOMEM; - } - rtlpriv = hw->priv; - SET_IEEE80211_DEV(hw, &intf->dev); - udev = interface_to_usbdev(intf); - usb_get_dev(udev); - usb_priv = rtl_usbpriv(hw); - memset(usb_priv, 0, sizeof(*usb_priv)); - usb_priv->dev.intf = intf; - usb_priv->dev.udev = udev; - usb_set_intfdata(intf, hw); - /* init cfg & intf_ops */ - rtlpriv->rtlhal.interface = INTF_USB; - rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_info); - rtlpriv->intf_ops = &rtl_usb_ops; - rtl_dbgp_flag_init(hw); - /* Init IO handler */ - _rtl_usb_io_handler_init(&udev->dev, hw); - rtlpriv->cfg->ops->read_chip_version(hw); - /*like read eeprom and so on */ - rtlpriv->cfg->ops->read_eeprom_info(hw); - if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't init_sw_vars.\n")); - goto error_out; - } - rtlpriv->cfg->ops->init_sw_leds(hw); - err = _rtl_usb_init(hw); - err = _rtl_usb_init_sw(hw); - /* Init mac80211 sw */ - err = rtl_init_core(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate sw for mac80211.\n")); - goto error_out; - } - - /*init rfkill */ - /* rtl_init_rfkill(hw); */ - - err = ieee80211_register_hw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Can't register mac80211 hw.\n")); - goto error_out; - } else { - rtlpriv->mac80211.mac80211_registered = 1; - } - set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); - return 0; -error_out: - rtl_deinit_core(hw); - _rtl_usb_io_handler_release(hw); - ieee80211_free_hw(hw); - usb_put_dev(udev); - return -ENODEV; -} -EXPORT_SYMBOL(rtl_usb_probe); - -void rtl_usb_disconnect(struct usb_interface *intf) -{ - struct ieee80211_hw *hw = usb_get_intfdata(intf); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); - struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); - - if (unlikely(!rtlpriv)) - return; - /*ieee80211_unregister_hw will call ops_stop */ - if (rtlmac->mac80211_registered == 1) { - ieee80211_unregister_hw(hw); - rtlmac->mac80211_registered = 0; - } else { - rtl_deinit_deferred_work(hw); - rtlpriv->intf_ops->adapter_stop(hw); - } - /*deinit rfkill */ - /* rtl_deinit_rfkill(hw); */ - rtl_usb_deinit(hw); - rtl_deinit_core(hw); - rtlpriv->cfg->ops->deinit_sw_leds(hw); - rtlpriv->cfg->ops->deinit_sw_vars(hw); - _rtl_usb_io_handler_release(hw); - usb_put_dev(rtlusb->udev); - usb_set_intfdata(intf, NULL); - ieee80211_free_hw(hw); -} -EXPORT_SYMBOL(rtl_usb_disconnect); - -int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message) -{ - return 0; -} -EXPORT_SYMBOL(rtl_usb_suspend); - -int rtl_usb_resume(struct usb_interface *pusb_intf) -{ - return 0; -} -EXPORT_SYMBOL(rtl_usb_resume); diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.h b/trunk/drivers/net/wireless/rtlwifi/usb.h deleted file mode 100644 index c83311655104..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/usb.h +++ /dev/null @@ -1,164 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - *****************************************************************************/ - -#ifndef __RTL_USB_H__ -#define __RTL_USB_H__ - -#include -#include - -#define RTL_USB_DEVICE(vend, prod, cfg) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ - .idVendor = (vend), \ - .idProduct = (prod), \ - .driver_info = (kernel_ulong_t)&(cfg) - -#define USB_HIGH_SPEED_BULK_SIZE 512 -#define USB_FULL_SPEED_BULK_SIZE 64 - - -#define RTL_USB_MAX_TXQ_NUM 4 /* max tx queue */ -#define RTL_USB_MAX_EP_NUM 6 /* max ep number */ -#define RTL_USB_MAX_TX_URBS_NUM 8 - -enum rtl_txq { - /* These definitions shall be consistent with value - * returned by skb_get_queue_mapping - *------------------------------------*/ - RTL_TXQ_BK, - RTL_TXQ_BE, - RTL_TXQ_VI, - RTL_TXQ_VO, - /*------------------------------------*/ - RTL_TXQ_BCN, - RTL_TXQ_MGT, - RTL_TXQ_HI, - - /* Must be last */ - __RTL_TXQ_NUM, -}; - -struct rtl_ep_map { - u32 ep_mapping[__RTL_TXQ_NUM]; -}; - -struct _trx_info { - struct rtl_usb *rtlusb; - u32 ep_num; -}; - -static inline void _rtl_install_trx_info(struct rtl_usb *rtlusb, - struct sk_buff *skb, - u32 ep_num) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - info->rate_driver_data[0] = rtlusb; - info->rate_driver_data[1] = (void *)(__kernel_size_t)ep_num; -} - - -/* Add suspend/resume later */ -enum rtl_usb_state { - USB_STATE_STOP = 0, - USB_STATE_START = 1, -}; - -#define IS_USB_STOP(rtlusb_ptr) (USB_STATE_STOP == (rtlusb_ptr)->state) -#define IS_USB_START(rtlusb_ptr) (USB_STATE_START == (rtlusb_ptr)->state) -#define SET_USB_STOP(rtlusb_ptr) \ - do { \ - (rtlusb_ptr)->state = USB_STATE_STOP; \ - } while (0) - -#define SET_USB_START(rtlusb_ptr) \ - do { \ - (rtlusb_ptr)->state = USB_STATE_START; \ - } while (0) - -struct rtl_usb { - struct usb_device *udev; - struct usb_interface *intf; - enum rtl_usb_state state; - - /* Bcn control register setting */ - u32 reg_bcn_ctrl_val; - /* for 88/92cu card disable */ - u8 disableHWSM; - /*QOS & EDCA */ - enum acm_method acm_method; - /* irq . HIMR,HIMR_EX */ - u32 irq_mask[2]; - bool irq_enabled; - - u16 (*usb_mq_to_hwq)(u16 fc, u16 mac80211_queue_index); - - /* Tx */ - u8 out_ep_nums ; - u8 out_queue_sel; - struct rtl_ep_map ep_map; - - u32 max_bulk_out_size; - u32 tx_submitted_urbs; - struct sk_buff_head tx_skb_queue[RTL_USB_MAX_EP_NUM]; - - struct usb_anchor tx_pending[RTL_USB_MAX_EP_NUM]; - struct usb_anchor tx_submitted; - - struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, - struct sk_buff_head *); - int (*usb_tx_post_hdl)(struct ieee80211_hw *, - struct urb *, struct sk_buff *); - void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); - - /* Rx */ - u8 in_ep_nums ; - u32 in_ep; /* Bulk IN endpoint number */ - u32 rx_max_size; /* Bulk IN max buffer size */ - u32 rx_urb_num; /* How many Bulk INs are submitted to host. */ - struct usb_anchor rx_submitted; - void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, - struct sk_buff_head *); - void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); -}; - -struct rtl_usb_priv { - struct rtl_usb dev; - struct rtl_led_ctl ledctl; -}; - -#define rtl_usbpriv(hw) (((struct rtl_usb_priv *)(rtl_priv(hw))->priv)) -#define rtl_usbdev(usbpriv) (&((usbpriv)->dev)) - - - -int __devinit rtl_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id); -void rtl_usb_disconnect(struct usb_interface *intf); -int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message); -int rtl_usb_resume(struct usb_interface *pusb_intf); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/wifi.h b/trunk/drivers/net/wireless/rtlwifi/wifi.h index ae55efad7a19..d44d79613d2d 100644 --- a/trunk/drivers/net/wireless/rtlwifi/wifi.h +++ b/trunk/drivers/net/wireless/rtlwifi/wifi.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include "debug.h" @@ -119,9 +118,6 @@ enum hardware_type { HARDWARE_TYPE_NUM }; -#define IS_HARDWARE_TYPE_8192CE(rtlhal) \ - (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) - enum scan_operation_backup_opt { SCAN_OPT_BACKUP = 0, SCAN_OPT_RESTORE, @@ -772,7 +768,6 @@ struct rtl_tid_data { struct rtl_priv; struct rtl_io { struct device *dev; - struct mutex bb_mutex; /*PCI MEM map */ unsigned long pci_mem_end; /*shared mem end */ @@ -784,14 +779,10 @@ struct rtl_io { void (*write8_async) (struct rtl_priv *rtlpriv, u32 addr, u8 val); void (*write16_async) (struct rtl_priv *rtlpriv, u32 addr, u16 val); void (*write32_async) (struct rtl_priv *rtlpriv, u32 addr, u32 val); - int (*writeN_async) (struct rtl_priv *rtlpriv, u32 addr, u16 len, - u8 *pdata); u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr); u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr); u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr); - int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len, - u8 *pdata); }; @@ -896,7 +887,7 @@ struct rtl_security { }; struct rtl_dm { - /*PHY status for DM (dynamic management) */ + /*PHY status for DM */ long entry_min_undecoratedsmoothed_pwdb; long undecorated_smoothed_pwdb; /*out dm */ long entry_max_undecoratedsmoothed_pwdb; @@ -1110,7 +1101,6 @@ struct rtl_tcb_desc { struct rtl_hal_ops { int (*init_sw_vars) (struct ieee80211_hw *hw); void (*deinit_sw_vars) (struct ieee80211_hw *hw); - void (*read_chip_version)(struct ieee80211_hw *hw); void (*read_eeprom_info) (struct ieee80211_hw *hw); void (*interrupt_recognized) (struct ieee80211_hw *hw, u32 *p_inta, u32 *p_intb); @@ -1139,8 +1129,7 @@ struct rtl_hal_ops { void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, bool b_firstseg, bool b_lastseg, struct sk_buff *skb); - bool (*cmd_send_packet)(struct ieee80211_hw *hw, struct sk_buff *skb); - bool(*query_rx_desc) (struct ieee80211_hw *hw, + bool(*query_rx_desc) (struct ieee80211_hw *hw, struct rtl_stats *stats, struct ieee80211_rx_status *rx_status, u8 *pdesc, struct sk_buff *skb); @@ -1177,7 +1166,6 @@ struct rtl_intf_ops { int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb); int (*reset_trx_ring) (struct ieee80211_hw *hw); - bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb); /*pci */ void (*disable_aspm) (struct ieee80211_hw *hw); @@ -1191,35 +1179,11 @@ struct rtl_mod_params { int sw_crypto; }; -struct rtl_hal_usbint_cfg { - /* data - rx */ - u32 in_ep_num; - u32 rx_urb_num; - u32 rx_max_size; - - /* op - rx */ - void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); - void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, - struct sk_buff_head *); - - /* tx */ - void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); - int (*usb_tx_post_hdl)(struct ieee80211_hw *, struct urb *, - struct sk_buff *); - struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, - struct sk_buff_head *); - - /* endpoint mapping */ - int (*usb_endpoint_mapping)(struct ieee80211_hw *hw); - u16 (*usb_mq_to_hwq)(u16 fc, u16 mac80211_queue_index); -}; - struct rtl_hal_cfg { char *name; char *fw_name; struct rtl_hal_ops *ops; struct rtl_mod_params *mod_params; - struct rtl_hal_usbint_cfg *usb_interface_cfg; /*this map used for some registers or vars defined int HAL but used in MAIN */ @@ -1238,7 +1202,6 @@ struct rtl_locks { spinlock_t rf_ps_lock; spinlock_t rf_lock; spinlock_t lps_lock; - spinlock_t tx_urb_lock; }; struct rtl_works { @@ -1474,8 +1437,10 @@ Set subfield of little-endian 4-byte value to specified value. */ (_os).octet = (u8 *)(_octet); \ (_os).length = (_len); -#define CP_MACADDR(des, src) \ - memcpy((des), (src), ETH_ALEN) +#define CP_MACADDR(des, src) \ + ((des)[0] = (src)[0], (des)[1] = (src)[1],\ + (des)[2] = (src)[2], (des)[3] = (src)[3],\ + (des)[4] = (src)[4], (des)[5] = (src)[5]) static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) { diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_chip.c b/trunk/drivers/net/wireless/zd1211rw/zd_chip.c index a73a305d3cba..54f68f134ea7 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_chip.c @@ -142,9 +142,8 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr return 0; } -static int _zd_iowrite32v_async_locked(struct zd_chip *chip, - const struct zd_ioreq32 *ioreqs, - unsigned int count) +int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, + unsigned int count) { int i, j, r; struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; @@ -171,7 +170,7 @@ static int _zd_iowrite32v_async_locked(struct zd_chip *chip, ioreqs16[j+1].addr = ioreqs[i].addr; } - r = zd_usb_iowrite16v_async(&chip->usb, ioreqs16, count16); + r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16); #ifdef DEBUG if (r) { dev_dbg_f(zd_chip_dev(chip), @@ -181,20 +180,6 @@ static int _zd_iowrite32v_async_locked(struct zd_chip *chip, return r; } -int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, - unsigned int count) -{ - int r; - - zd_usb_iowrite16v_async_start(&chip->usb); - r = _zd_iowrite32v_async_locked(chip, ioreqs, count); - if (r) { - zd_usb_iowrite16v_async_end(&chip->usb, 0); - return r; - } - return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); -} - int zd_iowrite16a_locked(struct zd_chip *chip, const struct zd_ioreq16 *ioreqs, unsigned int count) { @@ -202,8 +187,6 @@ int zd_iowrite16a_locked(struct zd_chip *chip, unsigned int i, j, t, max; ZD_ASSERT(mutex_is_locked(&chip->mutex)); - zd_usb_iowrite16v_async_start(&chip->usb); - for (i = 0; i < count; i += j + t) { t = 0; max = count-i; @@ -216,9 +199,8 @@ int zd_iowrite16a_locked(struct zd_chip *chip, } } - r = zd_usb_iowrite16v_async(&chip->usb, &ioreqs[i], j); + r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j); if (r) { - zd_usb_iowrite16v_async_end(&chip->usb, 0); dev_dbg_f(zd_chip_dev(chip), "error zd_usb_iowrite16v. Error number %d\n", r); @@ -226,7 +208,7 @@ int zd_iowrite16a_locked(struct zd_chip *chip, } } - return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); + return 0; } /* Writes a variable number of 32 bit registers. The functions will split @@ -239,8 +221,6 @@ int zd_iowrite32a_locked(struct zd_chip *chip, int r; unsigned int i, j, t, max; - zd_usb_iowrite16v_async_start(&chip->usb); - for (i = 0; i < count; i += j + t) { t = 0; max = count-i; @@ -253,9 +233,8 @@ int zd_iowrite32a_locked(struct zd_chip *chip, } } - r = _zd_iowrite32v_async_locked(chip, &ioreqs[i], j); + r = _zd_iowrite32v_locked(chip, &ioreqs[i], j); if (r) { - zd_usb_iowrite16v_async_end(&chip->usb, 0); dev_dbg_f(zd_chip_dev(chip), "error _zd_iowrite32v_locked." " Error number %d\n", r); @@ -263,7 +242,7 @@ int zd_iowrite32a_locked(struct zd_chip *chip, } } - return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); + return 0; } int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_def.h b/trunk/drivers/net/wireless/zd1211rw/zd_def.h index 5463ca9ebc01..6ac597ffd3b9 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_def.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_def.h @@ -45,7 +45,7 @@ typedef u16 __nocast zd_addr_t; #ifdef DEBUG # define ZD_ASSERT(x) \ do { \ - if (unlikely(!(x))) { \ + if (!(x)) { \ pr_debug("%s:%d ASSERT %s VIOLATED!\n", \ __FILE__, __LINE__, __stringify(x)); \ dump_stack(); \ diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c index 81e80489a052..f6df3665fdb6 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1156,7 +1156,6 @@ void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, memset(usb, 0, sizeof(*usb)); usb->intf = usb_get_intf(intf); usb_set_intfdata(usb->intf, hw); - init_usb_anchor(&usb->submitted_cmds); init_usb_interrupt(usb); init_usb_tx(usb); init_usb_rx(usb); @@ -1635,15 +1634,15 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, udev = zd_usb_to_usbdev(usb); prepare_read_regs_int(usb); - r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 50 /* ms */); + r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), + req, req_len, &actual_req_len, 50 /* ms */); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error in usb_interrupt_msg(). Error number %d\n", r); + "error in usb_bulk_msg(). Error number %d\n", r); goto error; } if (req_len != actual_req_len) { - dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n" + dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()\n" " req_len %d != actual_req_len %d\n", req_len, actual_req_len); r = -EIO; @@ -1664,103 +1663,13 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, return r; } -static void iowrite16v_urb_complete(struct urb *urb) -{ - struct zd_usb *usb = urb->context; - - if (urb->status && !usb->cmd_error) - usb->cmd_error = urb->status; -} - -static int zd_submit_waiting_urb(struct zd_usb *usb, bool last) -{ - int r = 0; - struct urb *urb = usb->urb_async_waiting; - - if (!urb) - return 0; - - usb->urb_async_waiting = NULL; - - if (!last) - urb->transfer_flags |= URB_NO_INTERRUPT; - - usb_anchor_urb(urb, &usb->submitted_cmds); - r = usb_submit_urb(urb, GFP_KERNEL); - if (r) { - usb_unanchor_urb(urb); - dev_dbg_f(zd_usb_dev(usb), - "error in usb_submit_urb(). Error number %d\n", r); - goto error; - } - - /* fall-through with r == 0 */ -error: - usb_free_urb(urb); - return r; -} - -void zd_usb_iowrite16v_async_start(struct zd_usb *usb) -{ - ZD_ASSERT(usb_anchor_empty(&usb->submitted_cmds)); - ZD_ASSERT(usb->urb_async_waiting == NULL); - ZD_ASSERT(!usb->in_async); - - ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); - - usb->in_async = 1; - usb->cmd_error = 0; - usb->urb_async_waiting = NULL; -} - -int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout) -{ - int r; - - ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); - ZD_ASSERT(usb->in_async); - - /* Submit last iowrite16v URB */ - r = zd_submit_waiting_urb(usb, true); - if (r) { - dev_dbg_f(zd_usb_dev(usb), - "error in zd_submit_waiting_usb(). " - "Error number %d\n", r); - - usb_kill_anchored_urbs(&usb->submitted_cmds); - goto error; - } - - if (timeout) - timeout = usb_wait_anchor_empty_timeout(&usb->submitted_cmds, - timeout); - if (!timeout) { - usb_kill_anchored_urbs(&usb->submitted_cmds); - if (usb->cmd_error == -ENOENT) { - dev_dbg_f(zd_usb_dev(usb), "timed out"); - r = -ETIMEDOUT; - goto error; - } - } - - r = usb->cmd_error; -error: - usb->in_async = 0; - return r; -} - -int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, - unsigned int count) +int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, + unsigned int count) { int r; struct usb_device *udev; struct usb_req_write_regs *req = NULL; - int i, req_len; - struct urb *urb; - struct usb_host_endpoint *ep; - - ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); - ZD_ASSERT(usb->in_async); + int i, req_len, actual_req_len; if (count == 0) return 0; @@ -1776,23 +1685,17 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, return -EWOULDBLOCK; } - udev = zd_usb_to_usbdev(usb); - - ep = usb_pipe_endpoint(udev, usb_sndintpipe(udev, EP_REGS_OUT)); - if (!ep) - return -ENOENT; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) - return -ENOMEM; + ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); + BUILD_BUG_ON(sizeof(struct usb_req_write_regs) + + USB_MAX_IOWRITE16_COUNT * sizeof(struct reg_data) > + sizeof(usb->req_buf)); + BUG_ON(sizeof(struct usb_req_write_regs) + + count * sizeof(struct reg_data) > + sizeof(usb->req_buf)); req_len = sizeof(struct usb_req_write_regs) + count * sizeof(struct reg_data); - req = kmalloc(req_len, GFP_KERNEL); - if (!req) { - r = -ENOMEM; - goto error; - } + req = (void *)usb->req_buf; req->id = cpu_to_le16(USB_REQ_WRITE_REGS); for (i = 0; i < count; i++) { @@ -1801,44 +1704,28 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, rw->value = cpu_to_le16(ioreqs[i].value); } - usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), - req, req_len, iowrite16v_urb_complete, usb, - ep->desc.bInterval); - urb->transfer_flags |= URB_FREE_BUFFER | URB_SHORT_NOT_OK; - - /* Submit previous URB */ - r = zd_submit_waiting_urb(usb, false); + udev = zd_usb_to_usbdev(usb); + r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), + req, req_len, &actual_req_len, 50 /* ms */); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error in zd_submit_waiting_usb(). " - "Error number %d\n", r); + "error in usb_bulk_msg(). Error number %d\n", r); + goto error; + } + if (req_len != actual_req_len) { + dev_dbg_f(zd_usb_dev(usb), + "error in usb_bulk_msg()" + " req_len %d != actual_req_len %d\n", + req_len, actual_req_len); + r = -EIO; goto error; } - /* Delay submit so that URB_NO_INTERRUPT flag can be set for all URBs - * of currect batch except for very last. - */ - usb->urb_async_waiting = urb; - return 0; + /* FALL-THROUGH with r == 0 */ error: - usb_free_urb(urb); return r; } -int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, - unsigned int count) -{ - int r; - - zd_usb_iowrite16v_async_start(usb); - r = zd_usb_iowrite16v_async(usb, ioreqs, count); - if (r) { - zd_usb_iowrite16v_async_end(usb, 0); - return r; - } - return zd_usb_iowrite16v_async_end(usb, 50 /* ms */); -} - int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) { int r; @@ -1907,15 +1794,15 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) } udev = zd_usb_to_usbdev(usb); - r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 50 /* ms */); + r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), + req, req_len, &actual_req_len, 50 /* ms */); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error in usb_interrupt_msg(). Error number %d\n", r); + "error in usb_bulk_msg(). Error number %d\n", r); goto out; } if (req_len != actual_req_len) { - dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()" + dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()" " req_len %d != actual_req_len %d\n", req_len, actual_req_len); r = -EIO; diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_usb.h b/trunk/drivers/net/wireless/zd1211rw/zd_usb.h index b3df2c8116cc..2d688f48a34c 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_usb.h @@ -217,11 +217,8 @@ struct zd_usb { struct zd_usb_rx rx; struct zd_usb_tx tx; struct usb_interface *intf; - struct usb_anchor submitted_cmds; - struct urb *urb_async_waiting; - int cmd_error; u8 req_buf[64]; /* zd_usb_iowrite16v needs 62 bytes */ - u8 is_zd1211b:1, initialized:1, was_running:1, in_async:1; + u8 is_zd1211b:1, initialized:1, was_running:1; }; #define zd_usb_dev(usb) (&usb->intf->dev) @@ -273,10 +270,6 @@ static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value, return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1); } -void zd_usb_iowrite16v_async_start(struct zd_usb *usb); -int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout); -int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, - unsigned int count); int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, unsigned int count); diff --git a/trunk/net/bluetooth/l2cap_sock.c b/trunk/net/bluetooth/l2cap_sock.c index adf41692daf3..21f5385ca24d 100644 --- a/trunk/net/bluetooth/l2cap_sock.c +++ b/trunk/net/bluetooth/l2cap_sock.c @@ -392,6 +392,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us switch (optname) { case L2CAP_OPTIONS: + memset(&opts, 0, sizeof(opts)); opts.imtu = l2cap_pi(sk)->imtu; opts.omtu = l2cap_pi(sk)->omtu; opts.flush_to = l2cap_pi(sk)->flush_to; diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index a42aa61269ea..775fb63471c4 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -664,13 +664,12 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) } static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, - struct sk_buff *req) + struct ieee80211_mgmt *mgmt, + size_t len) { - struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(req); - struct ieee80211_mgmt *mgmt = (void *)req->data; struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; - int tx_last_beacon, len = req->len; + int tx_last_beacon; struct sk_buff *skb; struct ieee80211_mgmt *resp; u8 *pos, *end; @@ -690,7 +689,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, mgmt->bssid, tx_last_beacon); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ - if (!tx_last_beacon && !(rx_status->rx_flags & IEEE80211_RX_RA_MATCH)) + if (!tx_last_beacon) return; if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && @@ -787,7 +786,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, switch (fc & IEEE80211_FCTL_STYPE) { case IEEE80211_STYPE_PROBE_REQ: - ieee80211_rx_mgmt_probe_req(sdata, skb); + ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); break; case IEEE80211_STYPE_PROBE_RESP: ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index f502634d43af..045b2fe4a414 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -832,8 +832,18 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) ieee80211_is_pspoll(hdr->frame_control)) && rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && rx->sdata->vif.type != NL80211_IFTYPE_WDS && - (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) + (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { + if ((!ieee80211_has_fromds(hdr->frame_control) && + !ieee80211_has_tods(hdr->frame_control) && + ieee80211_is_data(hdr->frame_control)) || + !(status->rx_flags & IEEE80211_RX_RA_MATCH)) { + /* Drop IBSS frames and frames for other hosts + * silently. */ + return RX_DROP_MONITOR; + } + return RX_DROP_MONITOR; + } return RX_CONTINUE; }