Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/padovan/blueto...
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 18 Feb 2011 21:49:17 +0000 (16:49 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 18 Feb 2011 21:49:17 +0000 (16:49 -0500)
39 files changed:
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/p54/eeprom.c
drivers/net/wireless/p54/eeprom.h
drivers/net/wireless/p54/fwio.c
drivers/net/wireless/p54/lmac.h
drivers/net/wireless/p54/main.c
drivers/net/wireless/p54/p54.h
drivers/net/wireless/p54/p54spi_eeprom.h
drivers/net/wireless/p54/txrx.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtlwifi/Makefile
drivers/net/wireless/rtlwifi/base.h
drivers/net/wireless/rtlwifi/debug.h
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
drivers/net/wireless/rtlwifi/rtl8192ce/fw.c
drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
drivers/net/wireless/rtlwifi/usb.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/usb.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/zd1211rw/zd_chip.c
drivers/net/wireless/zd1211rw/zd_def.h
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/wireless/zd1211rw/zd_usb.h
net/mac80211/ibss.c
net/mac80211/rx.c

index 56dee37..4d60583 100644 (file)
@@ -348,6 +348,7 @@ 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;
@@ -402,6 +403,7 @@ 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 */
index ed6e7d6..a4bdfdb 100644 (file)
@@ -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)
+       if ((avp->av_bcbuf == NULL) || !avp->is_bslot_active)
                return NULL;
 
        /* Release the old beacon first */
@@ -249,6 +249,7 @@ 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])
@@ -315,6 +316,7 @@ 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;
 }
@@ -749,3 +751,36 @@ 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);
+}
index 8469d7c..31f0fad 100644 (file)
@@ -1293,24 +1293,10 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc,
 {
        struct ath_vif *avp = (void *)vif->drv_priv;
 
-       /* 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);
-
+       ath9k_set_beaconing_status(sc, false);
        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)
@@ -1438,16 +1424,17 @@ 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);
        }
 }
 
@@ -1920,10 +1907,11 @@ 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_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+               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);
        }
 
        if (changed & BSS_CHANGED_ERP_SLOT) {
@@ -1946,8 +1934,12 @@ 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_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+       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_INT) {
                cur_conf->beacon_interval = bss_conf->beacon_int;
@@ -1957,10 +1949,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
                 */
                if (vif->type == NL80211_IFTYPE_AP) {
                        sc->sc_flags |= SC_OP_TSF_RESET;
-                       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+                       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);
                } else {
                        ath_beacon_config(sc, vif);
                }
index 3c5dd36..30483e2 100644 (file)
@@ -265,7 +265,8 @@ 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_setup_deferred_work,
+       .setup_deferred_work = iwlagn_bt_setup_deferred_work,
+       .cancel_deferred_work = iwlagn_bt_cancel_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,
index 3aa4864..325ff5c 100644 (file)
@@ -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 = 0;
+               bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED;
        } else {
                bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
                                        IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
@@ -1869,6 +1869,11 @@ 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
@@ -2022,6 +2027,11 @@ 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);
index 35b09aa..f54e15f 100644 (file)
@@ -55,6 +55,17 @@ 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)
@@ -87,13 +98,27 @@ 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->index - b->index;
+       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;
 }
 
 static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
@@ -145,25 +170,26 @@ 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 (list->channels[i].band != band)
+               if (chan->band != band)
                        continue;
 
-               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 ? "" :
+               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 ? "" :
                                   " [iqauto calibration data]"),
-                                 (list->channels[i].data & CHAN_HAS_LIMIT ? "" :
+                                 (chan->data & CHAN_HAS_LIMIT ? "" :
                                   " [output power limits]"),
-                                 (list->channels[i].data & CHAN_HAS_CURVE ? "" :
+                                 (chan->data & CHAN_HAS_CURVE ? "" :
                                   " [curve data]"),
-                                 list->channels[i].index, list->channels[i].freq);
+                                 chan->index, chan->freq);
                        continue;
                }
 
-               tmp->channels[j].band = list->channels[i].band;
-               tmp->channels[j].center_freq = list->channels[i].freq;
+               tmp->channels[j].band = chan->band;
+               tmp->channels[j].center_freq = chan->freq;
                j++;
        }
 
@@ -291,7 +317,7 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
                }
        }
 
-       /* sort the list by the channel index */
+       /* sort the channel list by frequency */
        sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
             p54_compare_channels, NULL);
 
@@ -410,33 +436,118 @@ 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 void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
-                            u16 type)
+static int p54_parse_rssical(struct ieee80211_hw *dev,
+                            u8 *data, int len, u16 type)
 {
        struct p54_common *priv = dev->priv;
-       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;
+       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;
 
-       if (len != (entry_size * num_entries)) {
-               wiphy_err(dev->wiphy,
-                         "unknown rssi calibration data packing type:(%x) len:%d.\n",
-                         type, len);
+               entries = (len - offset) /
+                       sizeof(struct pda_rssi_cal_ext_entry);
 
-               print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
-                                    data, len);
+               if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
+                   entries <= 0) {
+                       wiphy_err(dev->wiphy, "invalid rssi database.\n");
+                       goto err_data;
+               }
+       }
 
-               wiphy_err(dev->wiphy, "please report this issue.\n");
-               return;
+       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];
+
+               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;
+                       }
+
+                       entry[i].freq = freq;
+                       entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
+                       entry[i].add = (s16) le16_to_cpu(cal[i].add);
+               }
        }
 
-       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);
+       /* 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;
+               }
        }
+
+       return found < 0 ? &p54_rssi_default : &entry[found];
 }
 
 static void p54_parse_default_country(struct ieee80211_hw *dev,
@@ -627,21 +738,30 @@ 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:
-                       p54_parse_rssical(dev, entry->data, data_len,
-                                         le16_to_cpu(entry->code));
+                       err = p54_parse_rssical(dev, entry->data, data_len,
+                                               le16_to_cpu(entry->code));
+                       if (err)
+                               goto err;
                        break;
-               case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: {
-                       __le16 *src = (void *) entry->data;
-                       s16 *dst = (void *) &priv->rssical_db;
+               case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: {
+                       struct pda_custom_wrapper *pda = (void *) entry->data;
+                       __le16 *src;
+                       u16 *dst;
                        int i;
 
-                       if (data_len != sizeof(priv->rssical_db)) {
-                               err = -EINVAL;
-                               goto err;
-                       }
-                       for (i = 0; i < sizeof(priv->rssical_db) /
-                                       sizeof(*src); 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++)
                                *(dst++) = (s16) le16_to_cpu(*(src++));
+
                        }
                        break;
                case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
@@ -717,6 +837,8 @@ good_eeprom:
                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]);
@@ -727,9 +849,11 @@ err:
        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;
index 9051aef..afde72b 100644 (file)
@@ -81,6 +81,12 @@ 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;
@@ -179,6 +185,7 @@ 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
 
index 92b9b1f..0d3d108 100644 (file)
@@ -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,13 +503,14 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
        }
 
        rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
-       rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
-       rssi->add = cpu_to_le16(priv->rssical_db[band].add);
+       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);
        if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
                /* Longbow frontend needs ever more */
                rssi = (void *) skb_put(skb, sizeof(*rssi));
-               rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
-               rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
+               rssi->mul = cpu_to_le16(rssi_data->longbow_unkn);
+               rssi->add = cpu_to_le16(rssi_data->longbow_unk2);
        }
 
        if (priv->fw_var >= 0x509) {
@@ -523,6 +524,7 @@ 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:
index 04b63ec..5ca117e 100644 (file)
@@ -551,6 +551,7 @@ 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);
index 622d27b..0a78e66 100644 (file)
@@ -642,10 +642,12 @@ 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);
 }
index 43a3b2e..f951c8f 100644 (file)
@@ -116,7 +116,8 @@ struct p54_edcf_queue_param {
        __le16 txop;
 } __packed;
 
-struct p54_rssi_linear_approximation {
+struct p54_rssi_db_entry {
+       u16 freq;
        s16 mul;
        s16 add;
        s16 longbow_unkn;
@@ -197,13 +198,14 @@ 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_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
+       struct p54_cal_database *rssi_db;
        struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS];
 
        /* BBP/MAC state */
index d592cbd..0b7bfb0 100644 (file)
@@ -65,9 +65,10 @@ static unsigned char p54spi_eeprom[] = {
 0x03, 0x00, 0x00, 0x11,                /* PDR_ANTENNA_GAIN */
        0x08, 0x08, 0x08, 0x08,
 
-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,
+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,
 
 /* struct pda_custom_wrapper */
 0x10, 0x06, 0x5d, 0xb0,                /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */
@@ -671,7 +672,7 @@ static unsigned char p54spi_eeprom[] = {
        0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
 
 0x02, 0x00, 0x00, 0x00,                /* PDR_END */
-       0x67, 0x99,
+       0xb6, 0x04,
 };
 
 #endif /* P54SPI_EEPROM_H */
index f618b96..917d5d9 100644 (file)
@@ -273,11 +273,9 @@ 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->rssical_db[band].mul) / 64 +
-                        priv->rssical_db[band].add) / 4;
+               return ((rssi * priv->cur_rssi->mul) / 64 +
+                        priv->cur_rssi->add) / 4;
        } else {
                /*
                 * TODO: find the correct formula
index c9bf074..7a68a67 100644 (file)
@@ -773,13 +773,14 @@ 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 reg;
+       u32 orig_reg, 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, &reg);
+       orig_reg = reg;
        rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
        rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 
@@ -810,7 +811,14 @@ 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;
-       skb_pad(entry->skb, padding_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;
+       }
+
        beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
        rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
                                   entry->skb->len + padding_len);
index dd2164d..927a4a3 100644 (file)
@@ -1978,13 +1978,14 @@ 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 reg;
+       u32 orig_reg, reg;
 
        /*
         * Disable beaconing while we are reloading the beacon data,
         * otherwise we might be sending out invalid data.
         */
        rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       orig_reg = reg;
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
 
@@ -2002,7 +2003,14 @@ 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;
-       skb_pad(entry->skb, padding_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;
+       }
+
        beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
        rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
                                      entry_priv->desc, TXINFO_SIZE);
index 5ff72de..6e9981a 100644 (file)
@@ -1533,13 +1533,14 @@ 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 reg;
+       u32 orig_reg, reg;
 
        /*
         * Disable beaconing while we are reloading the beacon data,
         * otherwise we might be sending out invalid data.
         */
        rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       orig_reg = reg;
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
@@ -1563,7 +1564,14 @@ 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;
-       skb_pad(entry->skb, padding_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;
+       }
+
        beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
        rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
                                      entry->skb->len + padding_len);
index 2a7a438..efbff2f 100644 (file)
@@ -8,6 +8,7 @@ rtlwifi-objs    :=              \
                pci.o           \
                ps.o            \
                rc.o            \
-               regd.o
+               regd.o          \
+               usb.o
 
 obj-$(CONFIG_RTL8192CE)                += rtl8192ce/
index 3de5a14..c95982b 100644 (file)
@@ -30,6 +30,7 @@
 #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
index 08bdec2..e4aa868 100644 (file)
 #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
index 1758d44..a508ea5 100644 (file)
@@ -690,75 +690,6 @@ done:
 
 }
 
-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;
@@ -1273,7 +1204,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
        return 0;
 }
 
-unsigned int _rtl_mac_to_hwqueue(u16 fc,
+static unsigned int _rtl_mac_to_hwqueue(u16 fc,
                unsigned int mac80211_queue_index)
 {
        unsigned int hw_queue_index;
@@ -1312,7 +1243,7 @@ out:
        return hw_queue_index;
 }
 
-int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static 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));
@@ -1429,7 +1360,7 @@ int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        return 0;
 }
 
-void rtl_pci_deinit(struct ieee80211_hw *hw)
+static void rtl_pci_deinit(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -1444,7 +1375,7 @@ void rtl_pci_deinit(struct ieee80211_hw *hw)
 
 }
 
-int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
+static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        int err;
@@ -1461,7 +1392,7 @@ int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
        return 1;
 }
 
-int rtl_pci_start(struct ieee80211_hw *hw)
+static int rtl_pci_start(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -1496,7 +1427,7 @@ int rtl_pci_start(struct ieee80211_hw *hw)
        return 0;
 }
 
-void rtl_pci_stop(struct ieee80211_hw *hw)
+static void rtl_pci_stop(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -1838,7 +1769,7 @@ fail3:
        ieee80211_free_hw(hw);
 
        if (rtlpriv->io.pci_mem_start != 0)
-               pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+               pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
 
 fail2:
        pci_release_regions(pdev);
@@ -1888,7 +1819,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
        }
 
        if (rtlpriv->io.pci_mem_start != 0) {
-               pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+               pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
                pci_release_regions(pdev);
        }
 
index d36a669..0caa814 100644 (file)
@@ -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 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr);
+       return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
-       return readw((u8 *) rtlpriv->io.pci_mem_start + addr);
+       return readw((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
-       return readl((u8 *) rtlpriv->io.pci_mem_start + addr);
+       return readl((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
 {
-       writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
+       writeb(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline void pci_write16_async(struct rtl_priv *rtlpriv,
                                     u32 addr, u16 val)
 {
-       writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
+       writew(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline void pci_write32_async(struct rtl_priv *rtlpriv,
                                     u32 addr, u32 val)
 {
-       writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
+       writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
new file mode 100644 (file)
index 0000000..b08b780
--- /dev/null
@@ -0,0 +1,1388 @@
+/******************************************************************************
+ *
+ * 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 <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+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);
+       }
+}
index 62e7c64..ddf0a41 100644 (file)
 #include "dm.h"
 #include "fw.h"
 
-struct dig_t dm_digtable;
-static struct ps_t dm_pstable;
+#include "../rtl8192c/dm_common.c"
 
-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)
+void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -584,890 +115,4 @@ static 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);
-       }
-}
index 463439e..5911d52 100644 (file)
@@ -192,5 +192,6 @@ 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
index 11dd22b..b0776a3 100644 (file)
@@ -133,17 +133,15 @@ 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));
 
-       is_version_b = IS_CHIP_VER_B(version);
-       if (is_version_b) {
+       if (IS_CHIP_VER_B(version)) {
                u32 pageNums, remainSize;
                u32 page, offset;
 
-               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE)
+               if (IS_HARDWARE_TYPE_8192CE(rtlhal))
                        _rtl92c_fill_dummy(bufferPtr, &size);
 
                pageNums = size / FW_8192C_PAGE_SIZE;
@@ -231,14 +229,14 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
        u32 fwsize;
        int err;
        enum version_8192c version = rtlhal->version;
+       const struct firmware *firmware;
 
-       const struct firmware *firmware = NULL;
-
+       printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n",
+              rtlpriv->cfg->fw_name);
        err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
                               rtlpriv->io.dev);
        if (err) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Failed to request firmware!\n"));
+               printk(KERN_ERR "rtl8192cu: Firmware loading failed\n");
                return 1;
        }
 
@@ -560,39 +558,6 @@ 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
@@ -776,7 +741,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 = _rtl92c_cmd_send_packet(hw, skb);
+       rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb);
 
        if (rtstatus)
                b_dlok = true;
index 4504411..05f7a45 100644 (file)
@@ -37,6 +37,9 @@
 #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,
@@ -480,161 +483,129 @@ 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_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][0]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0]));
        }
        if (regaddr == RTXAGC_A_RATE54_24) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][1]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1]));
        }
        if (regaddr == RTXAGC_A_CCK1_MCS32) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][6]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6]));
        }
        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][7]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7]));
        }
        if (regaddr == RTXAGC_A_MCS03_MCS00) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][2]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2]));
        }
        if (regaddr == RTXAGC_A_MCS07_MCS04) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][3]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3]));
        }
        if (regaddr == RTXAGC_A_MCS11_MCS08) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][4]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4]));
        }
        if (regaddr == RTXAGC_A_MCS15_MCS12) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][5]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5]));
        }
        if (regaddr == RTXAGC_B_RATE18_06) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][8]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8]));
        }
        if (regaddr == RTXAGC_B_RATE54_24) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data;
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][9]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]));
        }
 
        if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data;
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][14]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]));
        }
 
        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data;
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][15]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]));
        }
 
        if (regaddr == RTXAGC_B_MCS03_MCS00) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data;
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][10]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]));
        }
 
        if (regaddr == RTXAGC_B_MCS07_MCS04) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data;
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][11]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]));
        }
 
        if (regaddr == RTXAGC_B_MCS11_MCS08) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data;
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][12]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]));
        }
 
        if (regaddr == RTXAGC_B_MCS15_MCS12) {
-               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
-                   data;
+               rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data;
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
                          rtlphy->pwrgroup_cnt,
-                         rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
-                                                           pwrgroup_cnt][13]));
+                         rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13]));
 
                rtlphy->pwrgroup_cnt++;
        }
index b366e88..a8b3d06 100644 (file)
@@ -135,6 +135,7 @@ 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 = {
index de1198c..0568d6d 100644 (file)
@@ -33,5 +33,7 @@
 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
index bf5852f..003bf10 100644 (file)
@@ -1029,3 +1029,36 @@ 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;
+}
index 53d0e0a..a5fcdfb 100644 (file)
@@ -711,4 +711,6 @@ 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/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
new file mode 100644 (file)
index 0000000..fbf24a0
--- /dev/null
@@ -0,0 +1,1035 @@
+/******************************************************************************
+ *
+ * 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 <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ *****************************************************************************/
+#include <linux/usb.h>
+#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/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h
new file mode 100644 (file)
index 0000000..c833116
--- /dev/null
@@ -0,0 +1,164 @@
+/******************************************************************************
+ *
+ * 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 <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_USB_H__
+#define __RTL_USB_H__
+
+#include <linux/usb.h>
+#include <linux/skbuff.h>
+
+#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
index d44d796..ae55efa 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/firmware.h>
 #include <linux/version.h>
 #include <linux/etherdevice.h>
+#include <linux/usb.h>
 #include <net/mac80211.h>
 #include "debug.h"
 
@@ -118,6 +119,9 @@ 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,
@@ -768,6 +772,7 @@ 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        */
@@ -779,10 +784,14 @@ 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);
 
 };
 
@@ -887,7 +896,7 @@ struct rtl_security {
 };
 
 struct rtl_dm {
-       /*PHY status for DM */
+       /*PHY status for DM (dynamic management) */
        long entry_min_undecoratedsmoothed_pwdb;
        long undecorated_smoothed_pwdb; /*out dm */
        long entry_max_undecoratedsmoothed_pwdb;
@@ -1101,6 +1110,7 @@ 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);
@@ -1129,7 +1139,8 @@ 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(*query_rx_desc) (struct ieee80211_hw *hw,
+       bool (*cmd_send_packet)(struct ieee80211_hw *hw, struct sk_buff *skb);
+       bool(*query_rx_desc) (struct ieee80211_hw *hw,
                               struct rtl_stats *stats,
                               struct ieee80211_rx_status *rx_status,
                               u8 *pdesc, struct sk_buff *skb);
@@ -1166,6 +1177,7 @@ 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);
@@ -1179,11 +1191,35 @@ 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 */
@@ -1202,6 +1238,7 @@ struct rtl_locks {
        spinlock_t rf_ps_lock;
        spinlock_t rf_lock;
        spinlock_t lps_lock;
+       spinlock_t tx_urb_lock;
 };
 
 struct rtl_works {
@@ -1437,10 +1474,8 @@ Set subfield of little-endian 4-byte value to specified value.   */
                (_os).octet = (u8 *)(_octet);           \
                (_os).length = (_len);
 
-#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])
+#define CP_MACADDR(des, src)           \
+       memcpy((des), (src), ETH_ALEN)
 
 static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr)
 {
index 54f68f1..a73a305 100644 (file)
@@ -142,8 +142,9 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
        return 0;
 }
 
-int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
-                  unsigned int count)
+static int _zd_iowrite32v_async_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];
@@ -170,7 +171,7 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
                ioreqs16[j+1].addr  = ioreqs[i].addr;
        }
 
-       r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16);
+       r = zd_usb_iowrite16v_async(&chip->usb, ioreqs16, count16);
 #ifdef DEBUG
        if (r) {
                dev_dbg_f(zd_chip_dev(chip),
@@ -180,6 +181,20 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
        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)
 {
@@ -187,6 +202,8 @@ 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;
@@ -199,8 +216,9 @@ int zd_iowrite16a_locked(struct zd_chip *chip,
                        }
                }
 
-               r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j);
+               r = zd_usb_iowrite16v_async(&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);
@@ -208,7 +226,7 @@ int zd_iowrite16a_locked(struct zd_chip *chip,
                }
        }
 
-       return 0;
+       return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */);
 }
 
 /* Writes a variable number of 32 bit registers. The functions will split
@@ -221,6 +239,8 @@ 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;
@@ -233,8 +253,9 @@ int zd_iowrite32a_locked(struct zd_chip *chip,
                        }
                }
 
-               r = _zd_iowrite32v_locked(chip, &ioreqs[i], j);
+               r = _zd_iowrite32v_async_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);
@@ -242,7 +263,7 @@ int zd_iowrite32a_locked(struct zd_chip *chip,
                }
        }
 
-       return 0;
+       return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */);
 }
 
 int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
index 6ac597f..5463ca9 100644 (file)
@@ -45,7 +45,7 @@ typedef u16 __nocast zd_addr_t;
 #ifdef DEBUG
 #  define ZD_ASSERT(x) \
 do { \
-       if (!(x)) { \
+       if (unlikely(!(x))) { \
                pr_debug("%s:%d ASSERT %s VIOLATED!\n", \
                        __FILE__, __LINE__, __stringify(x)); \
                dump_stack(); \
index f6df366..81e8048 100644 (file)
@@ -1156,6 +1156,7 @@ 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);
@@ -1634,15 +1635,15 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
 
        udev = zd_usb_to_usbdev(usb);
        prepare_read_regs_int(usb);
-       r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
-                        req, req_len, &actual_req_len, 50 /* ms */);
+       r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
+                             req, req_len, &actual_req_len, 50 /* ms */);
        if (r) {
                dev_dbg_f(zd_usb_dev(usb),
-                       "error in usb_bulk_msg(). Error number %d\n", r);
+                       "error in usb_interrupt_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()\n"
+               dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n"
                        " req_len %d != actual_req_len %d\n",
                        req_len, actual_req_len);
                r = -EIO;
@@ -1663,13 +1664,103 @@ error:
        return r;
 }
 
-int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
-                     unsigned int count)
+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 r;
        struct usb_device *udev;
        struct usb_req_write_regs *req = NULL;
-       int i, req_len, actual_req_len;
+       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);
 
        if (count == 0)
                return 0;
@@ -1685,17 +1776,23 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
                return -EWOULDBLOCK;
        }
 
-       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));
+       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;
 
        req_len = sizeof(struct usb_req_write_regs) +
                  count * sizeof(struct reg_data);
-       req = (void *)usb->req_buf;
+       req = kmalloc(req_len, GFP_KERNEL);
+       if (!req) {
+               r = -ENOMEM;
+               goto error;
+       }
 
        req->id = cpu_to_le16(USB_REQ_WRITE_REGS);
        for (i = 0; i < count; i++) {
@@ -1704,28 +1801,44 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
                rw->value = cpu_to_le16(ioreqs[i].value);
        }
 
-       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 */);
+       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);
        if (r) {
                dev_dbg_f(zd_usb_dev(usb),
-                       "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;
+                       "error in zd_submit_waiting_usb(). "
+                       "Error number %d\n", r);
                goto error;
        }
 
-       /* FALL-THROUGH with r == 0 */
+       /* 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;
 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;
@@ -1794,15 +1907,15 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
        }
 
        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 */);
+       r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
+                             req, req_len, &actual_req_len, 50 /* ms */);
        if (r) {
                dev_dbg_f(zd_usb_dev(usb),
-                       "error in usb_bulk_msg(). Error number %d\n", r);
+                       "error in usb_interrupt_msg(). Error number %d\n", r);
                goto out;
        }
        if (req_len != actual_req_len) {
-               dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()"
+               dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()"
                        " req_len %d != actual_req_len %d\n",
                        req_len, actual_req_len);
                r = -EIO;
index 2d688f4..b3df2c8 100644 (file)
@@ -217,8 +217,11 @@ 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;
+       u8 is_zd1211b:1, initialized:1, was_running:1, in_async:1;
 };
 
 #define zd_usb_dev(usb) (&usb->intf->dev)
@@ -270,6 +273,10 @@ 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);
 
index 775fb63..a42aa61 100644 (file)
@@ -664,12 +664,13 @@ 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 ieee80211_mgmt *mgmt,
-                                       size_t len)
+                                       struct sk_buff *req)
 {
+       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;
+       int tx_last_beacon, len = req->len;
        struct sk_buff *skb;
        struct ieee80211_mgmt *resp;
        u8 *pos, *end;
@@ -689,7 +690,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)
+       if (!tx_last_beacon && !(rx_status->rx_flags & IEEE80211_RX_RA_MATCH))
                return;
 
        if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 &&
@@ -786,7 +787,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, mgmt, skb->len);
+               ieee80211_rx_mgmt_probe_req(sdata, skb);
                break;
        case IEEE80211_STYPE_PROBE_RESP:
                ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len,
index 045b2fe..f502634 100644 (file)
@@ -832,18 +832,8 @@ 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)))) {
-               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;
-               }
-
+                    (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC))))
                return RX_DROP_MONITOR;
-       }
 
        return RX_CONTINUE;
 }