efuse.o         \
                ps.o            \
                rc.o            \
-               regd.o
+               regd.o          \
+               stats.o
 
 rtl8192c_common-objs +=                \
 
 obj-$(CONFIG_RTL8192CU)                += rtl8192cu/
 obj-$(CONFIG_RTL8192SE)                += rtl8192se/
 obj-$(CONFIG_RTL8192DE)                += rtl8192de/
+obj-$(CONFIG_RTL8723AE)                += rtl8723ae/
 
 ccflags-y += -D__CHECK_ENDIAN__
 
 }
 EXPORT_SYMBOL(rtlwifi_rate_mapping);
 
+bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       __le16 fc = rtl_get_fc(skb);
+
+       if (rtlpriv->dm.supp_phymode_switch &&
+           mac->link_state < MAC80211_LINKED &&
+           (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) {
+               if (rtlpriv->cfg->ops->check_switch_to_dmdp)
+                       rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
+       }
+       if (ieee80211_is_auth(fc)) {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
+               rtl_ips_nic_on(hw);
+
+               mac->link_state = MAC80211_LINKING;
+               /* Dual mac */
+               rtlpriv->phy.need_iqk = true;
+       }
+
+       return true;
+}
+
 void rtl_get_tcb_desc(struct ieee80211_hw *hw,
                      struct ieee80211_tx_info *info,
                      struct ieee80211_sta *sta,
 
 extern struct attribute_group rtl_attribute_group;
 int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
                         bool isht, u8 desc_rate, bool first_ampdu);
+bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
+
 #endif
 
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_sta_info *sta_entry = NULL;
        u8 tid = rtl_get_tid(skb);
+       __le16 fc = rtl_get_fc(skb);
 
        if (!sta)
                return false;
 
        if (!rtlpriv->rtlhal.earlymode_enable)
                return false;
+       if (ieee80211_is_nullfunc(fc))
+               return false;
+       if (ieee80211_is_qos_nullfunc(fc))
+               return false;
+       if (ieee80211_is_pspoll(fc))
+               return false;
        if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL)
                return false;
        if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE)
        u8 own;
        u8 temp_one = 1;
 
-       if (ieee80211_is_auth(fc)) {
-               RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
-               rtl_ips_nic_on(hw);
-       }
+       if (ieee80211_is_mgmt(fc))
+               rtl_tx_mgmt_proc(hw, skb);
 
        if (rtlpriv->psc.sw_ps_enabled) {
                if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) &&
                                 "8192 PCI-E is found - vid/did=%x/%x\n",
                                 venderid, deviceid);
                        rtlhal->hw_type = HARDWARE_TYPE_RTL8192E;
-                       break;
+                       return false;
                case RTL_PCI_REVISION_ID_8192SE:
                        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
                                 "8192SE is found - vid/did=%x/%x\n",
                        break;
 
                }
+       } else if (deviceid == RTL_PCI_8723AE_DID) {
+               rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+                        "8723AE PCI-E is found - "
+                        "vid/did=%x/%x\n", venderid, deviceid);
        } else if (deviceid == RTL_PCI_8192CET_DID ||
                   deviceid == RTL_PCI_8192CE_DID ||
                   deviceid == RTL_PCI_8191CE_DID ||
 
 #define RTL_PCI_8173_DID       0x8173  /*8191 SE Crab */
 #define RTL_PCI_8172_DID       0x8172  /*8191 SE RE */
 #define RTL_PCI_8171_DID       0x8171  /*8191 SE Unicron */
+#define RTL_PCI_8723AE_DID     0x8723  /*8723AE */
 #define RTL_PCI_0045_DID       0x0045  /*8190 PCI for Ceraga */
 #define RTL_PCI_0046_DID       0x0046  /*8190 Cardbus for Ceraga */
 #define RTL_PCI_0044_DID       0x0044  /*8192e PCIE for Ceraga */
 
         *      1M we will not use FW rate but user rate.
         */
        if (rtlmac->opmode == NL80211_IFTYPE_AP ||
-               rtlmac->opmode == NL80211_IFTYPE_ADHOC) {
+           rtlmac->opmode == NL80211_IFTYPE_ADHOC ||
+           rtlmac->opmode == NL80211_IFTYPE_MESH_POINT) {
                if (sta) {
                        sta_entry = (struct rtl_sta_info *) sta->drv_priv;
                        wireless_mode = sta_entry->wireless_mode;
 
--- /dev/null
+obj-m := rtl8723ae.o
+
+
+rtl8723ae-objs :=              \
+               dm.o            \
+               fw.o            \
+               hal_btc.o       \
+               hal_bt_coexist.o\
+               hw.o            \
+               led.o           \
+               phy.o           \
+               pwrseq.o        \
+               pwrseqcmd.o     \
+               rf.o            \
+               sw.o            \
+               table.o         \
+               trx.o           \
+
+
+obj-$(CONFIG_RTL8723AE) += rtl8723ae.o
+
+ccflags-y += -D__CHECK_ENDIAN__
 
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_sta_info *drv_priv = NULL;
        struct ieee80211_sta *sta = NULL;
-       long undecorated_smoothed_pwdb;
+       long undec_sm_pwdb;
 
        rcu_read_lock();
        if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
        /* adhoc or ap mode */
        if (sta) {
                drv_priv = (struct rtl_sta_info *) sta->drv_priv;
-               undecorated_smoothed_pwdb =
-                       drv_priv->rssi_stat.undecorated_smoothed_pwdb;
+               undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
        } else {
-               undecorated_smoothed_pwdb =
-                       rtlpriv->dm.undecorated_smoothed_pwdb;
+               undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
        }
 
-       if (undecorated_smoothed_pwdb < 0)
-               undecorated_smoothed_pwdb = pstatus->rx_pwdb_all;
-       if (pstatus->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
-               undecorated_smoothed_pwdb = (((undecorated_smoothed_pwdb) *
+       if (undec_sm_pwdb < 0)
+               undec_sm_pwdb = pstatus->rx_pwdb_all;
+       if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) {
+               undec_sm_pwdb = (((undec_sm_pwdb) *
                      (RX_SMOOTH_FACTOR - 1)) +
                     (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
-               undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + 1;
+               undec_sm_pwdb = undec_sm_pwdb + 1;
        } else {
-               undecorated_smoothed_pwdb = (((undecorated_smoothed_pwdb) *
-                     (RX_SMOOTH_FACTOR - 1)) +
+               undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) +
                     (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
        }
 
        if (sta) {
-               drv_priv->rssi_stat.undecorated_smoothed_pwdb =
-                       undecorated_smoothed_pwdb;
+               drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb;
        } else {
-               rtlpriv->dm.undecorated_smoothed_pwdb =
-                                        undecorated_smoothed_pwdb;
+               rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
        }
        rcu_read_unlock();
 
 
        RT_CID_819x_WNC_COREGA = 31,
        RT_CID_819x_Foxcoon = 32,
        RT_CID_819x_DELL = 33,
+       RT_CID_819x_PRONETS = 34,
+       RT_CID_819x_Edimax_ASUS = 35,
+       RT_CID_NETGEAR = 36,
+       RT_CID_PLANEX = 37,
+       RT_CID_CC_C = 38,
 };
 
 enum hw_descs {
        RTL_IMR_ROK,            /*Receive DMA OK Interrupt */
        RTL_IBSS_INT_MASKS,     /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK |
                                 * RTL_IMR_TBDER) */
+       RTL_IMR_C2HCMD,         /*fw interrupt*/
 
        /*CCK Rates, TxHT = 0 */
        RTL_RC_CCK_RATE1M,
        ACT_DELBA = 2,
 };
 
+enum rt_polarity_ctl {
+       RT_POLARITY_LOW_ACT = 0,
+       RT_POLARITY_HIGH_ACT = 1,
+};
+
 struct octet_string {
        u8 *octet;
        u16 length;
        u8 num_total_rfpath;
        struct phy_parameters hwparam_tables[MAX_TAB];
        u16 rf_pathmap;
+
+       enum rt_polarity_ctl polarity_ctl;
 };
 
 #define MAX_TID_COUNT                          9
        /*QOS & EDCA */
        struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE];
        struct rtl_qos_parameters ac[AC_MAX];
+
+       /* counters */
+       u64 last_txok_cnt;
+       u64 last_rxok_cnt;
+       u32 last_bt_edca_ul;
+       u32 last_bt_edca_dl;
+};
+
+struct btdm_8723 {
+       bool all_off;
+       bool agc_table_en;
+       bool adc_back_off_on;
+       bool b2_ant_hid_en;
+       bool low_penalty_rate_adaptive;
+       bool rf_rx_lpf_shrink;
+       bool reject_aggre_pkt;
+       bool tra_tdma_on;
+       u8 tra_tdma_nav;
+       u8 tra_tdma_ant;
+       bool tdma_on;
+       u8 tdma_ant;
+       u8 tdma_nav;
+       u8 tdma_dac_swing;
+       u8 fw_dac_swing_lvl;
+       bool ps_tdma_on;
+       u8 ps_tdma_byte[5];
+       bool pta_on;
+       u32 val_0x6c0;
+       u32 val_0x6c8;
+       u32 val_0x6cc;
+       bool sw_dac_swing_on;
+       u32 sw_dac_swing_lvl;
+       u32 wlan_act_hi;
+       u32 wlan_act_lo;
+       u32 bt_retry_index;
+       bool dec_bt_pwr;
+       bool ignore_wlan_act;
+};
+
+struct bt_coexist_8723 {
+       u32 high_priority_tx;
+       u32 high_priority_rx;
+       u32 low_priority_tx;
+       u32 low_priority_rx;
+       u8 c2h_bt_info;
+       bool c2h_bt_info_req_sent;
+       bool c2h_bt_inquiry_page;
+       u32 bt_inq_page_start_time;
+       u8 bt_retry_cnt;
+       u8 c2h_bt_info_original;
+       u8 bt_inquiry_page_cnt;
+       struct btdm_8723 btdm;
 };
 
 struct rtl_hal {
        struct ieee80211_hw *hw;
-
+       struct bt_coexist_8723 hal_coex_8723;
        bool up_first_time;
-       bool first_init;
        bool being_init_adapter;
        bool bbrf_ready;
 
 };
 
 struct rtl_stats {
+       u8 psaddr[ETH_ALEN];
        u32 mac_time[2];
        s8 rssi;
        u8 signal;
        void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t);
        void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw);
        void (*dm_dynamic_txpower) (struct ieee80211_hw *hw);
+       void (*c2h_command_handle) (struct ieee80211_hw *hw);
        void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw,
                                             bool mstate);
        void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);
        struct dig_t dm_digtable;
        struct ps_t dm_pstable;
 
-       /* data buffer pointer for USB reads */
-       __le32 *usb_data;
-       int usb_data_index;
+       /* section shared by individual drivers */
+       union {
+               struct {        /* data buffer pointer for USB reads */
+                       __le32 *usb_data;
+                       int usb_data_index;
+                       bool initialized;
+               };
+               struct {        /* section for 8723ae */
+                       bool reg_init;  /* true if regs saved */
+                       u32 reg_874;
+                       u32 reg_c70;
+                       u32 reg_85c;
+                       u32 reg_a74;
+                       bool bt_operation_on;
+               };
+       };
 
        /*This must be the last item so
           that it points to the data allocated
        BT_CSR_BC4 = 3,
        BT_CSR_BC8 = 4,
        BT_RTL8756 = 5,
+       BT_RTL8723A = 6,
 };
 
 enum bt_cur_state {
 
        bool fw_coexist_all_off;
        bool sw_coexist_all_off;
-       u32 current_state;
+       bool hw_coexist_all_off;
+       u32 cstate;
        u32 previous_state;
+       u32 cstate_h;
+       u32 previous_state_h;
+
        u8 bt_pre_rssi_state;
+       u8 bt_pre_rssi_state1;
 
        u8 reg_bt_iso;
        u8 reg_bt_sco;
-
+       bool balance_on;
+       u8 bt_active_zero_cnt;
+       bool cur_bt_disabled;
+       bool pre_bt_disabled;
+
+       u8 bt_profile_case;
+       u8 bt_profile_action;
+       bool bt_busy;
+       bool hold_for_bt_operation;
+       u8 lps_counter;
 };